frame.zc

来自「实现树形结构」· ZC 代码 · 共 743 行 · 第 1/2 页

ZC
743
字号
//[of]:license
//[c]Code Browser - a folding text editor for programmers
//[c]Copyright (C) 2003-07 Marc Kerbiquet
//[c]
//[c]This program is free software; you can redistribute it and/or modify
//[c]it under the terms of the GNU General Public License as published by
//[c]the Free Software Foundation; either version 2 of the License, or
//[c](at your option) any later version.
//[c]
//[c]This program is distributed in the hope that it will be useful,
//[c]but WITHOUT ANY WARRANTY; without even the implied warranty of
//[c]MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//[c]GNU General Public License for more details.
//[c]
//[c]You should have received a copy of the GNU General Public License
//[c]along with this program; if not, write to the Free Software
//[c]Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//[cf]
//[of]:imports
import "base/types"
import "base/memory"
import "base/memory-allocator"
import "collection/vector"
import "text/string"
import "text/string-buffer"
//[c]
import "graphics/geometry"
import "user/box"
import "user/menu"
import "user/command"
import "user/accelerator"
import "user/keyboard"
import "toolbox/clipboard"
//[c]
import "glib/glib"
import "glib/glib-object"
import "gdk/gdk"
import "gtk/gtk"
import "private/sys-command"
import "private/sys-menu"
//[c]
private [name="c"] import def gtk_resources : [1] []char
//[cf]
//[c]
//[of]:manager
//[of]:description
//[c]Functions to find and communicates with another instance.
//[cf]
//[of]:private
private func swift message atom
	return gdk_atom_intern ("_SWIFT_MESSAGE", FALSE)
end
//[c]
private func swift command atom
	return gdk_atom_intern ("_SWIFT_COMMAND", FALSE)
end
//[c]
//[cf]
//[c]
//[of]:can send message (manager)
//[c]Returns true if there is a manager with the given name
//[c]
public func can send message (name: string)
	def manager = gdk_atom_intern (name, FALSE)
	return check_selection_owner_get (manager)
end
//[cf]
//[of]:send message (manager, message)
public func send message (name: string, message: string)

	// There is a manager, send the message
	
	// We have to create a window to send the message :-(
	def window = gtk_window_new (GTK_WINDOW_TOPLEVEL) : GtkWindow
	g_signal_connect (window, "selection-get", ^selection get (GtkWidget, GtkSelectionData, guint, guint, string):GCallback, message)
	gtk_widget_realize (window)
	
	// Prepare the window for reception of the message request (the manager
	// will call us back to get the message)
	def manager = gdk_atom_intern (name, FALSE)
	def rcp atom = swift message atom
	gtk_selection_add_target (window, rcp atom, GDK_TARGET_STRING, 1)
	gtk_selection_owner_set (window,  rcp atom, GDK_CURRENT_TIME)

	// Send notification to the manager that we want to send a message
	gtk_selection_convert (window, manager, swift command atom, GDK_CURRENT_TIME)
	
	// Wait for call back from the manager
	gtk_main

	gtk_widget_unrealize (window)

end
//[c]
//[c]Sub-functions:
//[of]:	selection get
private func selection get (
		widget: GtkWidget, 
		data: GtkSelectionData, 
		info: guint,
		time: guint, 
		message: string)

	// send data
	gtk_selection_data_set (
		data,
		target (data),
		8,
		message: [] guchar,
		size (message): gint)

	// exit from the message loop
	gtk_main_quit

end
//[cf]
//[cf]
//[cf]
//[of]:frame box
//[of]:type
public struct frame box : local box
	private vbox: GtkVBox
	private parent frame: frame box
	private accel group: GtkAccelGroup
	private icon id: resource id

	public
		running: bool
		active: box
		menu: menu
		title: string
		is dialog: bool
end
//[cf]
//[of]:instance creation
//[of]:new frame box (style)
public func new frame box (style: box style)

	equ s = sizeof local frame box
	def f = allocate memory (s): frame box
	initialize (f, style)
	return f

end
//[cf]
//[of]:new frame box (parent)
public func new frame box (parent: box, style: box style)

	equ s = sizeof local frame box
	def f = allocate memory (s): frame box
	initialize (f, parent, style)
	return f

end
//[cf]
//[cf]
//[of]:operations
//[of]:activate
//[c]Shows the frame
//[c]
//[c]Defined in box...
//[cf]
//[of]:modal loop
public func modal loop (m: frame box)

	gtk_window_set_modal (window (m), TRUE)
	gtk_window_set_transient_for (window (m), window (parent frame (m)))

	message loop (m)

	// Must restore focus immediately
	if not nil (parent frame (m))
		set focus (parent frame (m))
	end

end
//[cf]
//[of]:do modal loop
public equ do modal loop (m: frame box)

	gtk_window_set_modal (window (m), TRUE)
	gtk_window_set_transient_for (window (m), window (parent frame (m)))

	while process message (m, false)
		yield
	end

	// Must restore focus immediately
	if not nil (parent frame (m))
		set focus (parent frame (m))
	end

end
//[cf]
//[of]:message loop
public func message loop (m: frame box)

	gtk_main

end
//[cf]
//[of]:process message
//[c]Processes one message
//[c]
//[c]	Returns false to exit a message loop
//[c]
public func process message (m: frame box, wait: bool)

	gtk_main_iteration_do (bool to gboolean (wait))
	return running (m)

end
//[cf]
//[of]:close
public func close (m: frame box)

	if query close (m)
		gtk_widget_destroy (widget (m))
	end
	
end
//[cf]
//[cf]
//[of]:menu
//[of]:set menu (menu)
//[c]Sets the menu
//[c]
public func set menu (m: frame box, menu: menu)

	menu (m) = menu

	// setup accelerators
	scan menu (m, menu)

end
//[c]
//[c]Sub-functions:
//[of]:scan menu (frame box, menu base)
//[c]Setup accelerators according to command found in menu
//[c]
private func scan menu (f: frame box, m: menu base) : void

	if is menu (m)
		equ menu = m : menu
		each (menu) ? child
			scan menu (f, child)
		end
	elsif ~ is separator (m)
		equ item = m : menu item
		def cmd = cmd (item)
		register shortcut (f, item)
	end

end
//[cf]
//[cf]
//[of]:append menu (menu, cmd)
//[c]Adds a command a sub-menu
//[c]
//[c]A registered command will be scanned for short cut
//[c]
//[c]This method must be used when adding a menu item
//[c]in menu after call to configure menu (...)
//[c]
public func append menu (m: frame box, popup: menu, cmd: command)

	def menu item = append menu (popup, cmd)		
	register shortcut (m, menu item)

end
//[cf]
//[of]:remove menu (menu, index)
//[c]Removes a menu item from a sub-menu
//[c]
//[c]This method removes the item and unregister any shortcut associated to it.
//[c]
public func remove menu (m: frame box, popup: menu, index: dword)

	def child = child (popup, index)
	if ~ is menu (child) && ~ is separator (child)
		unregister shortcut (m, child : menu item)
	end
	
	remove menu (popup, index)

end
//[cf]
//[cf]
//[of]:icon
//[of]:set icon (icon)
//[c]
public func set icon (m: frame box, icon id: resource id)

	icon id (m) = icon id
	update icon (m)

end
//[cf]
//[c]
//[cf]
//[of]:title
//[of]:set title (text)
public func set title (m: frame box, text: string)

	gtk_window_set_title (window (m), to UTF8 (text))

end
//[cf]
//[c]
//[cf]
//[of]:geometry
//[of]:set default size (width, height)
public func set default size (
		m: frame box, 
		w: int,
		h: int)

	gtk_window_set_default_size (window (m), w, h)

end
//[cf]
//[cf]
//[of]:manager
//[of]:set manager (manager)
//[c]This frame can receive a message from another process when 
//[c]invoking send message with the same name.
//[c]
public func set manager (m: frame box, name: string)

	def atom = gdk_atom_intern (name, FALSE)
	gtk_selection_add_target (widget (m), atom, swift command atom, 1)
	gtk_selection_owner_set (
		widget (m), 
		atom,
		GDK_CURRENT_TIME)

end
//[cf]
//[cf]
//[c]
//[of]:restricted
//[of]:initialize (parent, style)
//[c]
public func initialize (m: frame box, parent: box, style: box style)

	def w = gtk_window_new (GTK_WINDOW_TOPLEVEL) : GtkWindow
	widget (m) = w
	connect (m, "delete_event", ^delete event (GtkWidget, GdkEvent, frame box))
	connect (m, "focus-in-event", ^focus in event (GtkWindow, GdkEventFocus, frame box))
	connect (m, "focus-out-event", ^focus out event (GtkWindow, GdkEventFocus, frame box))

	def accel group = gtk_accel_group_new
	accel group (m) = accel group
	gtk_window_add_accel_group (w, accel group)

	def vbox = gtk_vbox_new (FALSE, 0) : GtkVBox
	vbox (m) = vbox
	gtk_container_add (widget (m): GtkContainer, vbox)
	gtk_widget_show (vbox)
	g_signal_connect (vbox, "realize", ^realize vbox(GtkWidget, object):GCallback, nil)
	
	// special handling of parent: the frame must not
	// be insterted in the tree of the parent
	initialize (super (m), nil)
	set style (m, style)
	class (m) = frame box class
	active (m) = nil
	menu (m) = nil
	icon id (m) = 0
	running (m) = true

	is dialog (m) = false

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?