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 함수로 이렇게 쓸 수 있고,
해당 위치로 윈도우가 이동해야 되겠고,
윈도우가 위로 올라와야지
마우스로 문서창을 클릭했는데도 사전 창이 계속 올라와 있으면 불편하니까..
그걸 방지하기 위해 이런 코드도 넣어주고.
팝업 사전에서 핵심이 위에서 말한 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 | | | |
| | | | | | | |
| | | +------------------+ | | |
| | +----------------------+ | |
| +--------------------------+ |
+------------------------------+
이거를 구현해보자구.
해당 위치로 윈도우가 이동해야 되겠고, gdk_device_get_position (device, NULL, &x, &y); gtk_window_move (GTK_WINDOW (dict->window), x + 10, y + 15);
디씨 버그
drag, paste 를 두번했더니... gdk_device_get_remove_style_tag;">(device, NULL, &x, &y); 이렇게 나와버렸네
2화 3화는 왜 념글 못 갔누..