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