18.3.1 サンプルプログラムの全体


*_コールバック関数を使うための準備
#include "modclbk.as"
    newclbk3 cb_win_delete_event, 3, *on_win_delete_event, CLBKMODE_CDECL@
    newclbk3 cb_rbtn1_toggled, 2, *on_rbtn1_toggled, CLBKMODE_CDECL@
    newclbk3 cb_rbtn2_toggled, 2, *on_rbtn2_toggled, CLBKMODE_CDECL@
    newclbk3 cb_iview_drag_data_get, 6, *on_iview_drag_data_get, CLBKMODE_CDECL@
    newclbk3 cb_lbl_drag_data_received, 8, *on_lbl_drag_data_received, CLBKMODE_CDECL@
    newclbk3 cb_g_list_free_full, 1, *on_g_list_free_full, CLBKMODE_CDECL@

*_GTKの関数を使うための準備
#uselib "libgtk-3-0.dll"
#func global gtk_init "gtk_init" sptr, sptr

#func global gtk_settings_get_default "gtk_settings_get_default"
#func global gtk_settings_set_string_property "gtk_settings_set_string_property" sptr, sptr, sptr, sptr

#func global gtk_window_new "gtk_window_new" int
#func global gtk_widget_show_all "gtk_widget_show_all" sptr
#func global gtk_container_add "gtk_container_add" sptr, sptr

#func global gtk_main "gtk_main"
#func global gtk_main_quit "gtk_main_quit"

#func global gtk_box_new "gtk_box_new" int, int
#func global gtk_box_pack_start "gtk_box_pack_start" sptr, sptr, int, int, int

#func global gtk_list_store_new2 "gtk_list_store_new" int, int, int
#func global gtk_list_store_append "gtk_list_store_append" sptr, sptr
#func global gtk_list_store_set2 "gtk_list_store_set" sptr, sptr, sptr, sptr, sptr, sptr, int
#func global gtk_tree_model_get_iter "gtk_tree_model_get_iter" sptr, sptr, sptr
#func global gtk_tree_path_free "gtk_tree_path_free" sptr
#func global gtk_tree_model_get1 "gtk_tree_model_get" sptr, sptr, int, sptr, int
#func global gtk_tree_path_to_string "gtk_tree_path_to_string" sptr
#func global gtk_tree_path_new_from_string "gtk_tree_path_new_from_string" sptr

#func global gtk_selection_data_set_text "gtk_selection_data_set_text" sptr, sptr, int
#func global gtk_selection_data_get_text "gtk_selection_data_get_text" sptr
#func global gtk_selection_data_set_pixbuf "gtk_selection_data_set_pixbuf" sptr, sptr
#func global gtk_selection_data_get_pixbuf "gtk_selection_data_get_pixbuf" sptr
#func global gtk_selection_data_get_length "gtk_selection_data_get_length" sptr

#func global gtk_image_new "gtk_image_new"
#func global gtk_widget_render_icon_pixbuf "gtk_widget_render_icon_pixbuf" sptr, sptr, int

#func global gtk_icon_view_new_with_model "gtk_icon_view_new_with_model" sptr
#func global gtk_icon_view_set_pixbuf_column "gtk_icon_view_set_pixbuf_column" sptr, int
#func global gtk_icon_view_set_text_column "gtk_icon_view_set_text_column" sptr, int
#func global gtk_icon_view_set_item_orientation "gtk_icon_view_set_item_orientation" sptr, int
#func global gtk_icon_view_set_columns "gtk_icon_view_set_columns" sptr, int
#func global gtk_icon_view_enable_model_drag_source "gtk_icon_view_enable_model_drag_source" sptr, int, sptr, int, int
#func global gtk_icon_view_get_selected_items "gtk_icon_view_get_selected_items" sptr
#func global gtk_icon_view_get_model "gtk_icon_view_get_model" sptr
#func global gtk_icon_view_set_selection_mode "gtk_icon_view_set_selection_mode" sptr, int

#func global gtk_label_new "gtk_label_new" sptr

#func global gtk_drag_dest_set "gtk_drag_dest_set" sptr, int, sptr, int, int
#func global gtk_target_list_new "gtk_target_list_new" sptr, int
#func global gtk_target_list_add_text_targets "gtk_target_list_add_text_targets" sptr, int
#func global gtk_drag_dest_set_target_list "gtk_drag_dest_set_target_list" sptr, sptr
#func global gtk_drag_source_set_target_list "gtk_drag_source_set_target_list" sptr, sptr

#func global gtk_radio_button_new_with_label_from_widget "gtk_radio_button_new_with_label_from_widget"  sptr, str
#func global gtk_toggle_button_get_active "gtk_toggle_button_get_active" sptr

#func global gtk_dialog_new "gtk_dialog_new"
#func global gtk_window_set_title "gtk_window_set_title" sptr, sptr
#func global gtk_dialog_get_content_area "gtk_dialog_get_content_area" sptr
#func global gtk_image_new_from_pixbuf "gtk_image_new_from_pixbuf" sptr
#func global gtk_dialog_add_button "gtk_dialog_add_button" sptr, sptr, int
#func global gtk_dialog_run "gtk_dialog_run" sptr
#func global gtk_widget_destroy "gtk_widget_destroy" sptr

#uselib "libgobject-2.0-0.dll"
#define g_signal_connect(%1, %2, %3, %4) g_signal_connect_data %1, %2, %3, %4, 0, 0
#func global g_signal_connect_data "g_signal_connect_data" sptr, str, sptr, sptr, int, int
#func global g_object_unref "g_object_unref" sptr

#uselib "libgdk_pixbuf-2.0-0.dll"
#func global gdk_pixbuf_get_type "gdk_pixbuf_get_type"

#uselib "libglib-2.0-0.dll"
#func global g_list_length "g_list_length" sptr
#func global g_list_nth_data "g_list_nth_data"  sptr, int
#func global g_list_free_full "g_list_free_full" sptr, sptr
#func global g_free "g_free" sptr

*_よく使う関数
#include "hspinet.as"
#module
#defcfunc u str chars_ ; shift-jis文字列をutf-8に変換
    chars = chars_
    nkfcnv@ chars, chars, "Sw"
    return chars
#global

*_よく使う定数
#const TRUE 1 ; 真
#const FALSE 0 ; 偽
#const NULL 0 ; ヌルポインタ

*_GTK初期化
    gtk_init NULL, NULL

*_GTKのデフォルトGUIフォントを変更
    gtk_settings_get_default
    gtk_settings_set_string_property stat, "gtk-font-name", "ms ui gothic, 10", NULL

*_ウィンドウ生成
#const GTK_WINDOW_TOPLEVEL 0 ; GtkWindowType
    gtk_window_new GTK_WINDOW_TOPLEVEL
    win = stat
    g_signal_connect win, "delete-event", cb_win_delete_event, NULL

*_VBox生成
#const GTK_ORIENTATION_VERTICAL 1 ; GtkOrientation
    gtk_box_new GTK_ORIENTATION_VERTICAL, 12
    vbox = stat

*_HBox1生成
#const GTK_ORIENTATION_HORIZONTAL 0 ; GtkOrientation
    gtk_box_new GTK_ORIENTATION_HORIZONTAL, 12
    hbox1 = stat

*_IconView用データ生成
    ; GtkTreeIter格納用変数作成
    sdim struct_itr, ( 4 * 4 ) ; 4*4 = GtkTreeIter構造体サイズ
    itr = varptr( struct_itr )

    ; GtkListStore生成
#enum COLUMN_NAME = 0 ; GtkListStoreデータの項目インデックス
#enum COLUMN_ICON
#enum NUM_COLUMN ; 項目数
#define G_TYPE_STRING G_TYPE_MAKE_FUNDAMENTAL(16) ; GObject - Type Information
#define ctype G_TYPE_MAKE_FUNDAMENTAL(%1) (%1 << 2)
    gdk_pixbuf_get_type
    gtk_list_store_new2 NUM_COLUMN, G_TYPE_STRING, stat
    mdl = stat

    ; GtkListStoreにデータをセット
#define GTK_STOCK_ABOUT "gtk-about" ; GtkStockItem
#define GTK_STOCK_CONVERT "gtk-convert"
#define GTK_STOCK_COPY "gtk-copy"
#const GTK_ICON_SIZE_DND 5 ; GtkIconSize
    icons = GTK_STOCK_ABOUT, GTK_STOCK_CONVERT, GTK_STOCK_COPY
    repeat length( icons )
        gtk_list_store_append mdl, itr
        gtk_image_new
        gtk_widget_render_icon_pixbuf stat, icons( cnt ), GTK_ICON_SIZE_DND
        pixbuf = stat
        gtk_list_store_set2 mdl, itr, COLUMN_NAME, "item " + ( cnt + 1 ), COLUMN_ICON, pixbuf, -1
        g_object_unref pixbuf
    loop

*_IconView生成
#const GTK_SELECTION_MULTIPLE 3 ; GtkSelectionMode
#const GDK_MODIFIER_MASK ( 0x5c001fff ) ; GdkModifierType
#const GDK_ACTION_COPY (1 << 1) ; GdkDragAction
#const GDK_ACTION_MOVE (1 << 2)
    gtk_icon_view_new_with_model mdl
    iview = stat
    gtk_icon_view_set_text_column iview, COLUMN_NAME
    gtk_icon_view_set_pixbuf_column iview, COLUMN_ICON
    gtk_icon_view_set_item_orientation iview, GTK_ORIENTATION_VERTICAL
    gtk_icon_view_set_columns iview, 1
    gtk_icon_view_set_selection_mode iview, GTK_SELECTION_MULTIPLE
/* 複数項目のドラッグドロップは一応可能だが、操作が少し面倒。
   (1) アイコン選択時の最後のクリックで押したマウスボタンを放さずにそのままドラッグ操作を始めなければならない。
       ドラッグ操作開始のためのクリックを別に行うと、アイコンの選択状態が変化してしまう。
       ここは、例えばWindowsのエクスプローラとはまったく挙動が違う。
   (2) actionsにGDK_ACTION_MOVEフラグを立てない(移動モード:オフ)の場合、Shiftキーを押しながら選択したアイコンをドロップする時には、Shiftキーを放さないとドロップできない。
       GDK_ACTION_MOVEフラグを立てればドロップできるが、ドラッグ元のアイコン削除が自動で実行されてしまう上に、最後に選択したアイコンしか削除されない。
       これを修正するには、残っている被選択アイコン(モデルデータ)を削除するために、drag-endシグナルのハンドラを書かなければならない? */
    actions = GDK_ACTION_COPY | GDK_ACTION_MOVE
    gtk_icon_view_enable_model_drag_source iview, GDK_MODIFIER_MASK, NULL, 0, actions
    g_signal_connect iview, "drag-data-get", cb_iview_drag_data_get, NULL

*_Label生成
    gtk_label_new u( "ここにアイコンをドロップしてください。" )
    lbl = stat
#const GTK_DEST_DEFAULT_ALL 0x07 ; GtkDestDefaults
    gtk_drag_dest_set lbl, GTK_DEST_DEFAULT_ALL, NULL, 0, actions
    g_signal_connect lbl, "drag-data-received", cb_lbl_drag_data_received, NULL

*_GtkTargetList初期化
#enum TARGET_TEXT = 0 ; ドラッグドロップで最終的にやりとりするデータの型のID
#enum TARGET_PIXBUF
    gtk_target_list_new NULL, 0
    tlist_text = stat
    gtk_target_list_add_text_targets tlist_text, TARGET_TEXT
    gtk_target_list_new NULL, 0
    tlist_pixbuf = stat
    gtk_target_list_add_text_targets tlist_pixbuf, TARGET_PIXBUF
    gtk_drag_source_set_target_list iview, tlist_pixbuf
    gtk_drag_dest_set_target_list lbl, tlist_pixbuf

*_HBox2生成
    gtk_box_new GTK_ORIENTATION_HORIZONTAL, 12
    hbox2 = stat

*_ターゲット切り替え用トグルボタン生成
    gtk_radio_button_new_with_label_from_widget  NULL, "Image"
    rbtn1 = stat
    g_signal_connect rbtn1, "toggled", cb_rbtn1_toggled, NULL
    gtk_radio_button_new_with_label_from_widget  rbtn1, "Text"
    rbtn2 = stat
    g_signal_connect rbtn2, "toggled", cb_rbtn2_toggled, NULL

*_ウィンドウの組み立て
    gtk_box_pack_start hbox1, iview, TRUE, TRUE, 0
    gtk_box_pack_start hbox1, lbl, TRUE, TRUE, 0
    gtk_box_pack_start hbox2, rbtn1, TRUE, FALSE, 0
    gtk_box_pack_start hbox2, rbtn2, TRUE, FALSE, 0
    gtk_box_pack_start vbox, hbox1, TRUE, TRUE, 0
    gtk_box_pack_start vbox, hbox2, FALSE, FALSE, 0
    gtk_container_add win, vbox

*_ウィンドウの表示とメインループの開始
    gtk_widget_show_all win
    gtk_main
    end

*_シグナルハンドラ
*on_win_delete_event
    gtk_main_quit
    return

*on_rbtn1_toggled
    clbkargprotect args_
    gtk_toggle_button_get_active args_( 0 )
    if stat {
        gtk_drag_source_set_target_list iview, tlist_pixbuf
        gtk_drag_dest_set_target_list lbl, tlist_pixbuf
    }
    return

*on_rbtn2_toggled
    clbkargprotect args_
    gtk_toggle_button_get_active args_( 0 )
    if stat {
        gtk_drag_source_set_target_list iview, tlist_text
        gtk_drag_dest_set_target_list lbl, tlist_text
    }
    return

*on_iview_drag_data_get
    clbkargprotect args_
    widget = args_( 0 )
    data = args_( 2 )
    info = args_( 3 )

    gtk_icon_view_get_selected_items widget
    treepaths = stat
    g_list_length treepaths
    len_list = stat
    itemlist = ""

    repeat len_list
        g_list_nth_data treepaths, cnt
        path = stat

        if info = TARGET_PIXBUF {
            gtk_tree_path_to_string path
            ptr = stat
            dupptr str_path, ptr, 64, 2
            itemlist += str_path + "\n"
            g_free ptr
            goto *@f
        }
        if info = TARGET_TEXT {
            gtk_tree_model_get_iter mdl, itr, path
            gtk_tree_model_get1 mdl, itr, COLUMN_NAME, varptr( ptr ), -1
            dupptr name, ptr, 1024, 2
            itemlist += name + "\n"
            g_free ptr
            goto *@f
        }
*@
    loop
    gtk_selection_data_set_text data, varptr( itemlist ), -1
    g_list_free_full treepaths, cb_g_list_free_full
    return

*on_lbl_drag_data_received
    clbkargprotect args_
    data = args_( 4 )
    info = args_( 5 )

    gtk_selection_data_get_length data
    len = stat
    gtk_selection_data_get_text data
    dupptr text, stat, ( len + 1 ), 2
    split text, "\n", items
    num = stat

    if info = TARGET_TEXT {
        repeat num
            if items(cnt) ! "" {
                mes "アイテム\"" + items(cnt) + "\"がドロップされました。"
            }
        loop
        goto *@f
    }
    if info = TARGET_PIXBUF {
        gtk_dialog_new
        dlg = stat
        gtk_window_set_title dlg, u( "ドロップされたアイコン" )

        gtk_dialog_get_content_area dlg
        area = stat
        repeat num
            if items(cnt) ! "" {
                gtk_tree_path_new_from_string items(cnt)
                gtk_tree_model_get_iter mdl, itr, stat
                gtk_tree_model_get1 mdl, itr, COLUMN_ICON, varptr( pixbuf ), -1
                gtk_image_new_from_pixbuf pixbuf
                img = stat
                gtk_box_pack_start area, img, FALSE, FALSE, 10
                g_object_unref pixbuf
            }
        loop

#define GTK_STOCK_OK "gtk-ok" ; GtkStockItem
#const GTK_RESPONSE_OK -5 ; GtkResponseType
        gtk_dialog_add_button dlg, GTK_STOCK_OK, GTK_RESPONSE_OK

        gtk_widget_show_all dlg
        gtk_dialog_run dlg
        gtk_widget_destroy dlg
        goto *@f
    }
*@
    return

*_GList開放用コールバック関数
*on_g_list_free_full
    clbkargprotect args_
    gtk_tree_path_free args_( 0 )
    return

Prev - Table of contents - Next

odymatter_0_110.html">Next