KJAVA虚拟机Hack笔记-用GTK+实现Form

 


KJAVA虚拟机Hack笔记-用GTK+实现Form


Form是一个窗口,在上面可以放控件和命令。Form上可以放很多个控件,一个屏幕可能显示不下,所以在适当的时候需要滚动条,而且只能出现垂直滚动条。为了实现垂直滚动功能,我们先在窗口上放一个滚动窗口:


form = gtk_window_new (GTK_WINDOW_TOPLEVEL);

scrolledwindow = gtk_scrolled_window_new (NULL, NULL);

gtk_widget_show (scrolledwindow);

gtk_container_add (GTK_CONTAINER (form), scrolledwindow);

gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);

viewport = gtk_viewport_new (NULL, NULL);

gtk_widget_show (viewport);

gtk_container_add (GTK_CONTAINER (scrolledwindow), viewport);


用vbox来负责控件的排版:


container = gtk_vbox_new (FALSE, 3);

gtk_widget_show (container);

gtk_container_add (GTK_CONTAINER (viewport), container);


命令用菜单来实现:


menubar = gtk_menu_bar_new ();

gtk_widget_show (menubar);

gtk_box_pack_start (GTK_BOX (container), menubar, FALSE, FALSE, 0);


lfpport_form_create的实现如下:


MidpError lfpport_form_create(MidpDisplayable* dispPtr,

                  const pcsl_string* title, const pcsl_string* tickerText)

{

    GtkWidget* widget = create_form();

    dispPtr->frame.widgetPtr      = widget;

    dispPtr->frame.show           = gtk_frame_show;

    dispPtr->frame.hideAndDelete  = gtk_frame_hide_and_delete;

    dispPtr->frame.handleEvent    = form_handle_event;

    dispPtr->setTitle             = displayable_set_title;

    dispPtr->setTicker            = displayable_set_ticker;


    dispPtr->setTitle(dispPtr, title);

    displayable_set_ticker(dispPtr, tickerText);


    frame_hook_delete_event(widget);


    lfpport_set_active_screen(dispPtr->frame.widgetPtr);


    return KNI_OK;

}


里面几个虚函数很容易实现,其中实现gtk_frame_hide_and_delete时需要点技巧,因为在切换当前窗口时,MIDP先隐藏再显示,所以在切换的过程会闪一下背景窗口,为了避免这种情况,我们可以在idle里再销毁窗口。


lfpport_form_set_content_size设置viewpoint的大小:

MidpError lfpport_form_set_content_size(MidpDisplayable* dispPtr,

                    int w, int h)

{

    GtkWidget* widget = GTK_WIDGET(dispPtr->frame.widgetPtr);

    GtkWidget* viewport = lookup_widget(widget, "viewport");


    gtk_widget_set_size_request(viewport, w, h);


    return KNI_OK;

}


lfpport_form_set_current_item设置当前的焦点:


MidpError lfpport_form_set_current_item(MidpItem* itemPtr, int yOffset)

{

    GtkWidget* widget = GTK_WIDGET(itemPtr->widgetPtr);

    GtkWidget* item_widget = g_object_get_data(G_OBJECT(widget), "item_widget");


    gtk_widget_grab_focus(item_widget);


    (void)yOffset;


    return KNI_OK;

}


lfpport_form_get_scroll_position得到当前窗口的滚动条的位置:


MidpError lfpport_form_get_scroll_position(int *pos)

{

    GtkWidget* form = lfpport_get_active_screen();

    GtkWidget* swindow = form != NULL ? lookup_widget(form, "scrolledwindow"):NULL;


    if(swindow != NULL)

    {

        *pos = gtk_adjustment_get_value(gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WI

NDOW(swindow)));

    }


    return KNI_OK;

}


lfpport_form_set_scroll_position设置滚动条的位置:


MidpError lfpport_form_set_scroll_position(int pos)

{

    GtkWidget* form = lfpport_get_active_screen();

    GtkWidget* swindow = form != NULL ? lookup_widget(form, "scrolledwindow"):NULL;


    if(swindow != NULL)

    {

        gtk_adjustment_set_value(gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(sw

indow)), pos);

    }


    return KNI_OK;

}


lfpport_form_get_viewport_height得到viewpoint的高度:


MidpError lfpport_form_get_viewport_height(int *height)

{

    GtkWidget* form = lfpport_get_active_screen();

    GtkWidget* viewport = form != NULL ? lookup_widget(form, "viewport") : NULL;


    if(viewport != NULL)

    {

        *height = viewport->allocation.height;

    }


    return KNI_OK;

}


Category: KVM hack notes