glib, gtk 팝업 사전 만들기 4화


저번 편 복습을 조금 하자구..

저번 편에서 윈도우 하나 만들었잖아...

GtkWindow 로 만든 건 메인 윈도우임.

우리가 어플 실행하면 윈도우 떡하니 뜰텐데 그게 gtk_window_new (GTK_WINDOW_TOPLEVEL) 이걸로

만드는거임.

그리고, 전편에서 glib 함수도 좀 나왔는데...


g_slice_new

g_slice_free


이 함수를 쓰지 않고 g_malloc(malloc), g_free(free) 써도 되는데,


g_slice_new 로 할당된 메모리를 g_free() 로 해제하면 아마 에러 날거임.

g_slice_new      ... g_slice_free 이렇게 쌍으로 써야 되는거구.

g_malloc(malloc) ... g_free(free) 이렇게 쌍으로 써야 하는 것.


섞어쓰면 안 됨!! 에러날 거임

glib 에 메모리 관련 함수는

https://developer.gnome.org/glib/stable/glib-Memory-Allocation.html

에 잘 나와 있음.


signal 연결하는 함수, 이거는 자주 보게 될 거니까 지금 당장 몰라도 결국 알게됨. 걱정할 거 없음

g_signal_connect (dict->window, "destroy", (GCallback) on_destroy, NULL);

처음에 이 함수 다룰 때, 처음에 알쏭달쏭한 점이 있는데

dict->window 상속 관계가 이렇게 되거덩


    GObject

    ╰── GInitiallyUnowned

        ╰── GtkWidget

            ╰── GtkContainer

                ╰── GtkBin

                    ╰── GtkWindow


dict->window 요거를 signal 을 정의한 물건으로 형변환을 하지 않아도 위에 나오는 물건들에 정의된

signal 을 쓸 수 있음.

GtkBin 이라는 거는 컨테이너인데, 그 안에 물건이 1개밖에 안 들어감.

GtkWindow 가 GtkBin 을 상속했으니까 GtkWindow 에 물건이 1개밖에 안 들어감.

헐.. 어쩌지? ㅋㅋㅋ

그래서 여러 개의 물건을 넣을 수 있는 GtkBox 같은 컨테이너들이 준비되어 있지


    GObject

    ╰── GInitiallyUnowned

        ╰── GtkWidget

            ╰── GtkContainer

                ╰── GtkBox

                    ├── GtkAppChooserWidget

                    ├── GtkButtonBox

                    ├── GtkColorChooserWidget

                    ├── GtkColorSelection

                    ├── GtkFileChooserButton

                    ├── GtkFileChooserWidget

                    ├── GtkFontChooserWidget

                    ├── GtkFontSelection

                    ├── GtkHBox

                    ├── GtkInfoBar

                    ├── GtkRecentChooserWidget

                    ├── GtkShortcutsSection

                    ├── GtkShortcutsGroup

                    ├── GtkShortcutsShortcut

                    ├── GtkStackSwitcher

                    ├── GtkStatusbar

                    ╰── GtkVBox


GtkWindow 에 GtkBox 1개 넣고, GtkBox 에 여러 개 물건을 쳐 넣으면 됨!

GtkBox 는 활용도가 높으니까 그거 나중에 꼭 알아두셈.


    GObject

    ╰── GInitiallyUnowned

        ╰── GtkWidget

            ╰── GtkContainer

                ╰── GtkBin

                    ╰── GtkScrolledWindow


GtkWindow 에 GtkScrolledWindow 넣고

GtkScrolledWindow 에 GtkBox 넣으면 스크롤이 자동으로 됨.


사전 UI 를 이렇게 만들거임, 그럴싸하지? ㅋㅋ


+---------- GtkWindow ---------+

| +--------- GtkBox ---------+ |

| | +----------------------+ | |

| | |        toolbar       | | |

| | +----------------------+ | |

| |                          | |

| | +- GtkScrolledWindow --+ | |

| | | +------------------+ | | |

| | | |                  | | | |

| | | |    GtkTextView   | | | |

| | | |                  | | | |

| | | +------------------+ | | |

| | +----------------------+ | |

| +--------------------------+ |

+------------------------------+


X윈도 시스템에서 마우스로 텍스트를 더블 클릭하면 X서버에 PRIMARY 라는 Atom (여러 어플에서 공유가

가능한 메모리, 컴퓨터 과학에서 말하는 공유 메모리(shared memory) 기법 아님)에 저장됨.

아마 내부적으로 IPC 기법으로 구현되었을 것 같음.

XInternAtom(), XGetWindowProperty() 이용하여 PRIMARY 라는 Atom 에 들어있는 값을

읽어올 수 있는데, 이렇게 쓰면 불편하지. 편하라구 gtk 라는게 있는거임.


gtk 함수로 이렇게 쓸 수 있고,


clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY); handler_id = g_signal_connect (clipboard, "owner-change", (GCallback) on_owner_change, dict);


해당 위치로 윈도우가 이동해야 되겠고,


gdk_device_get_position (device, NULL, &x, &y); gtk_window_move (GTK_WINDOW (dict->window), x + 10, y + 15);


윈도우가 위로 올라와야지


gtk_window_set_keep_above (GTK_WINDOW (dict->window), TRUE); gtk_window_present (GTK_WINDOW (dict->window));


마우스로 문서창을 클릭했는데도 사전 창이 계속 올라와 있으면 불편하니까..

그걸 방지하기 위해 이런 코드도 넣어주고.


gtk_window_set_keep_above (GTK_WINDOW (dict->window), FALSE);


팝업 사전에서 핵심이 위에서 말한 GDK_SELECTION_PRIMARY, "owner-change" 이부분이지.

이걸 알아야 마우스로 더블 클릭했을 때, 바로 그 위치에 사전 창을 띄울 수 있는 거임.

그 다음 핵심이... 사전 데이터인데... 직접 데이터를 하나씩 넣을 수 GtkTextView 를 만들어

두는 거지. 외부에서 긁어온 걸로 db 만드는 방법도 있는데, 그게 법적으로 문제가 됨.

법적 문제 피해하려면 GtkTextView 대신에 Webkit 을 넣어서 사전 웹페이지를 받아다가 그려주는

방법이 있음. goldendict 가 그런 방식.

그러나 내가 원하는 건, 영문/중문 글을 읽다가 모르는 단어 나왔을 때, 웹 브라우저로 검색하다보면

정신이 산만해져서 집중이 저하되어 공부가 잘 안 되니까.. 조그맣게, 단어 밑에 뜨게 해서 직독직해에

방해되지 않도록 하려는 목적임. 구글 번역에서 제공하는 데이터 정도가 딱 좋은데, 그거 끌어다 쓰려면

돈내야 함 ㅠㅠ. 그렇게 바뀌었음. 그래서 사용자가 직접 단어/뜻을 입력할 수 있도록 GtkTextView 를

두는 거임. toolbar 에는 edit, save 이렇게 들어갈 거고,


db 로는 유닉스/리눅스에서 전통적으로 사용되던 dbm(ndbm, gdbm은 GPL임) 이거 사용할 거구.

나중에 확장하고 싶으면 미래에 sqlite 로 바꾸면 되지.

다음 편에서는


+---------- GtkWindow ---------+

| +--------- GtkBox ---------+ |

| | +----------------------+ | |

| | |        toolbar       | | |

| | +----------------------+ | |

| |                          | |

| | +- GtkScrolledWindow --+ | |

| | | +------------------+ | | |

| | | |                  | | | |

| | | |    GtkTextView   | | | |

| | | |                  | | | |

| | | +------------------+ | | |

| | +----------------------+ | |

| +--------------------------+ |

+------------------------------+


이거를 구현해보자구.