윈도우 프로그램은 보통 메뉴가 있습니다. 

가장 익숙한 인터페이스죠

이번 강좌에는 간단하게 프로그램을 종료 하는 메뉴를 하나 만들어 보겠습니다.

다음과 같이 package.json 파일을 만듭니다. 

----[package.json]--------------------------------------------------------------
{
"name": "exit menu",
"main": "index.html",
"window": 
{
"toolbar" : false
}
}
--------------------------------------------------------------------------------

그다음 index.html을 다음과 같이 만듭니다.

----[index.html]----------------------------------------------------------------
<html>
<head>
<meta http-equiv="content-Type" content="text/html; charset=utf-8" /> 
<title>종료 메뉴</title>
<script type="text/javascript" src="js/jquery-2.0.3.min.js"></script>
</head>
<body>
<h1>종료 메뉴</h1>
<script type="text/javascript" src="main.js"></script>  
</body>
</html>
--------------------------------------------------------------------------------

이제 메뉴를 구성해 봅시다. 

보통 메뉴는 상단에 메뉴바가 있습니다. 

이것을 저는 메인메뉴라고 하겠습니다 .

메인메뉴에는 메뉴항목으로 파일이라는 항목을 만들 겁니다. 

파일메뉴항목은 종료메뉴항목을 갖는 구성입니다. 

즉 이런 구성이죠


 파일
 -+----------------------------------------------------
  |
  +-- 종료

이런 구성을 프로그램적으로 메뉴 구성을 표현할 때 

기억해야 하는 것이 

메뉴와 메뉴항목을 구분해야 합니다. 

메뉴라고 하는 것은 일종의 뼈대 같은 겁니다. 

메뉴항목은 실제 우리가 선택하는 실제 내용이죠

메뉴는 그 자체만으로 의미가 없고 항상 메뉴항목을 포함하고 있어야 합니다. 

우리가 하고자 하는 구성에서는 두개의 메뉴가 존재합니다. 

하나는 상단에 바 형태로 표현되는 메뉴 인 메뉴바입니다. 

두번째는 메뉴바의 항목중 파일을 클릭했을 때 활성화 되는 파일메뉴입니다. 

메뉴바는 파일메뉴항목을 가지고 있습니다. 

파일메뉴는 종료메뉴항목을 가집니다. 

메뉴바와 파일메뉴는 별개라는 것을 기억해 주어야 합니다. 

이 두개의 연결은 파일메뉴항목에서 해 주어야 합니다. 

자 먼저 프로그램을 보면서 다시 한번 설명하겠습니다. 

main.js을 만들어 봅시다.

----[main.js]-------------------------------------------------------------------
$(function(){

var gui = require('nw.gui');
var win = gui.Window.get();

var 메인메뉴       = new gui.Menu({ type: 'menubar' });
var 파일메뉴   = new gui.Menu();

var 파일메뉴항목   = new gui.MenuItem({ label: '파일' });
var 종료메뉴항목    = new gui.MenuItem({ label: 'Exit'});

파일메뉴.append( 종료메뉴항목 );
파일메뉴항목.submenu = 파일메뉴;

메인메뉴.append( 파일메뉴항목 );

win.menu = 메인메뉴;

종료메뉴항목.click = function() {
gui.App.quit();
}
});
--------------------------------------------------------------------------------

먼저 메뉴를 다루기 위해서 다음 문장에 의해서 "nw.gui" 를 로드 합니다.

var gui = require('nw.gui');

그 다음 메뉴를 담을 윈도우를 지정하기 위해서 다음 문장을 수행합니다. 

var win = gui.Window.get();

앞으로 강좌에서는 위 두  부분에 대한 설명은 생략 할 겁니다.

이제 뼈대가 되는 두개의 메뉴를 생성 합니다. 

var 메인메뉴       = new gui.Menu({ type: 'menubar' });
var 파일메뉴   = new gui.Menu();

보통 메뉴를 생성할때는 그냥 

new gui.Menu();
을 사용합니다. 

하지만 가장 상단에 표현되는 메뉴바 형태로 할때는 메뉴의 타입을 다음과 같이 선택합니다. 

var 메인메뉴       = new gui.Menu({ type: 'menubar' });

이렇게 생성된 메인메뉴는 가장 마지막에 

다음과 같은 문장으로 윈도우와 연결하게 됩니다. 

win.menu = 메인메뉴;

이 문장만으로 메뉴가 생성되었고 윈도우에 메인메뉴는 연결하지만 아무것도 표현되지 않습니다. 

실제 메뉴를 구성하는 메뉴 항목이 없기 때문이죠..

그그래서 메뉴 항목을 다음과 같이 선언합니다. 

var 파일메뉴항목   = new gui.MenuItem({ label: '파일' });
var 종료메뉴항목    = new gui.MenuItem({ label: 'Exit'});

메뉴항목을 만들때 여러가지 옵션이 있지만 

이해를 쉽게 하기 위해서 우리는 label 만 정의 합니다. 

즉 메뉴에서 보여줄 항목 문자열만 선언하는 것이죠

이렇게 메뉴항목을 만들었다면 이 메뉴항목이 어떤 메뉴에 포함되는지 알려 주어야 합니다. 

이것은 메뉴의 연결 관계를 구현하는 것인데 

중요한 것은 처리 순서가 매우 중요하다는 것입니다. 

메뉴를 선언하거나 메뉴 항목을 만드는 것은 처리 순서가 중요하지 않지만 

메뉴를 서로 연결하는 과정은 

가장 마지막 항목부터 연결해서 꼭대기로 올라 가는 과정을 밟아가야 합니다.

그렇지 않으면 동작하지 않는다는 것을 기억해 주세요..

우리는 다음과 같은 연결 구성을 가지고 있습니다. 

win.menu --> 파일 --> Exit

이런 연결 구성을 가지기 때문에 가장 먼저 Exit 부터 처리해 주어야 합니다.

그래서 다음 문장을 통해서 

파일메뉴.append( 종료메뉴항목 );

파일메뉴에 종료메뉴항목을 포함시킵니다. 

이제 파일 메뉴에 대한 처리가 끝났다면 

파일 메뉴는 메인메뉴에 포함되어야 하는데 

메인메뉴의 메뉴항목으로 정의된 파일메뉴항목에 

다음과 같은 문장으로 파일메뉴를 연결 합니다.

파일메뉴항목.submenu = 파일메뉴;

이 문장은 파일메뉴항목은 서브 메뉴를 가지고 있고 

그 서브 메뉴가 파일메뉴임을 알려 줍니다. 

이제 파일메뉴항목을 메뉴파에 다음 문장으로 포함 시킵니다.

메인메뉴.append( 파일메뉴항목 );
마지막으로 메뉴바를 다음 문장으로 윈도우 메뉴에 연결합니다.

win.menu = 메인메뉴;
예제를 보면 종료메뉴항목을 클릭하면 프로그램을 종료하도록 하게 하는데 

저는 습관상 메뉴 구성 구현 부분과 메뉴 처리 부분을 따로 모아 구현합니다. 

메뉴 클릭 이벤트 처리는 나중에 선언해도 동작에는 문제가 없기 때문입니다. 

그래서 실행해 보면 다음과 같은 동작 메뉴가 나오고 
P001_메뉴 구현.png
[그림 ]

Exit 메뉴항목을 클릭하면 다음 문장으로 인하여

gui.App.quit();

프로그램이 종료 처리 되게 됩니다.


오늘은 내용이 조금 어렵죠?

하지만 찬찬히 보면 이렇게 메뉴가 구현 될 수 밖에 없습니다. 

프로그램 기법중 메뉴 처리가 어려운 부분이죠

그래도 이건 쉽게 메뉴가 구현되는 겁니다. 

만약 직접 메뉴를 모두 구현 한다고 해보세요 

아~~ 생각만 해도 싫습니다.