menu.zc
来自「实现树形结构」· ZC 代码 · 共 835 行 · 第 1/2 页
ZC
835 行
//[of]:new (i label command, recipient, components)
//[c]
//[c]DESCRIPTION
//[c] Creates a command from a label command initializer structure.
//[c]
//[c]ARGUMENTS
//[c] i is a pointer to the structures describing the label.
//[c] recipient is the object that will be passed to all commands defined in this menu.
//[c] c is an array to store labels
//[c]
//[c]RETURN VALUE
//[c] Returns a newly created popup object
//[c]
private func new (i: i label command, recipient: object, c: [] object)
def cmd = new (cmd (i), recipient)
c [label (i)] = cmd
return cmd
end
//[cf]
//[cf]
//[cf]
//[c]
//[of]:popup
//[of]:show popup (menu, pos, box)
//[c]
public func show popup (menu: menu, pos: point, owner: box)
def popup = popup menu (menu)
def id = g_signal_connect (
popup,
"deactivate",
^popup deactivated (GtkMenuShell, gpointer): GCallback,
nil)
gtk_menu_popup (
popup,
nil, // menu shell
nil, // menu item
nil, // func
nil, // data
0,
gtk_get_current_event_time)
gtk_main
g_signal_handler_disconnect (popup, id)
end
//[c]
private func popup deactivated (shell: GtkMenuShell, data: gpointer)
gtk_main_quit
end
//[cf]
//[cf]
//[of]:searching
//[of]:menu (m, id)
//[c]Returns the first child with given id
//[c]
public func menu (m: menu, id: int)
each (m) ? menu
if id == id (menu)
return menu
end
end
return nil
end
//[cf]
//[cf]
//[of]:enumerating
//[of]:each (m)
//[c]Enumerates children
//[c]
public equ each (menu: menu)
each (children (menu)) ? m
yield (m:menu base)
end
end
//[cf]
//[cf]
//[of]:adding - removing
//[of]:append menu (m, child menu)
//[c]
public func append menu (menu: menu, child: menu)
add (children (menu), child)
if is menu bar (menu)
gtk_menu_shell_append (menu bar (menu), menu item (child))
else
gtk_menu_shell_append (popup menu (menu), menu item (child))
end
end
//[cf]
//[of]:append menu (m, cmd)
//[c]
public func append menu (menu: menu, cmd: command)
def item = new menu item (cmd, menu)
add (children (menu), item)
gtk_menu_shell_append (popup menu (menu), menu item (item))
return item
end
//[cf]
//[of]:append separator (m)
//[c]
public func append separator (menu: menu)
def s = new menu separator
add (children (menu), s)
gtk_menu_shell_append (popup menu (menu), widget (s))
end
//[cf]
//[c]
//[of]:remove menu (m, index)
//[c]
public func remove menu (m: menu, index: dword)
delete (child (m, index))
remove (children (m), index)
end
//[cf]
//[cf]
//[of]:accessing
//[of]:child (m, index)
//[c]
public func child (m: menu, index: dword)
return children (m) [index] : menu base
end
//[cf]
//[of]:number of children (m)
//[c]
public func number of children (m: menu)
return size (children (m))
end
//[cf]
//[cf]
//[cf]
//[c]
//[c]private:
//[of]:menu base
//[of]:instance creation
//[of]:delete (m)
//[c]
private func delete (m: menu base)
if is menu (m)
delete (m: menu)
elsif is separator (m)
delete (m: menu separator)
else
delete (m: menu item)
end
end
//[cf]
//[cf]
//[cf]
//[of]:menu item
//[of]:instance creation
//[of]:new menu item (command, parent menu)
//[c]
private func new menu item (cmd: command, parent: menu)
def item = allocate memory (sizeof local menu item): menu item
id (item) = 0
is menu (item) = false
is separator (item) = false
accel group (item) = nil
cmd (item) = cmd
parent (item) = parent
caption (item) = nil
update caption (item)
// register the menu item as a listener on the command
initialize (listener (item), item, ^command event (menu item, command, command event))
add listener (cmd, listener (item))
// Creates the gtk object
def menu item = gtk_menu_item_new_with_mnemonic (to UTF8 (caption (item))) : GtkMenuItem
gtk_widget_show (menu item)
menu item (item) = menu item
update enabling (item)
g_signal_connect (
menu item,
"activate",
^activate (GtkMenuItem, menu item):GCallback,
item : gpointer)
g_signal_connect (
menu item,
"destroy",
^destroy (GtkMenuItem, menu item):GCallback,
item : gpointer)
return item
end
//[cf]
//[of]:delete (m)
//[c]
private func delete (item: menu item)
def w = menu item (item)
if not nil (w)
gtk_widget_destroy (w)
end
remove listener (cmd (item), listener (item))
if not nil (caption (item))
delete (caption (item))
end
free memory (item)
end
//[cf]
//[cf]
//[of]:updating
//[of]:update caption (m)
//[c]Updates the caption of the menu
//[c]
private func update caption (item: menu item)
def s = temp string buffer
// compute the new string in the buffer
append caption (caption (cmd (item)), s)
// update only if there is no previous value or if the
// new value differ from the previous one
def old = caption (item)
if is nil (old) || old <> as string (s)
caption (item) = new string (s)
if not nil (old)
delete (old)
end
end
release (s)
end
//[cf]
//[of]:update enabling (m)
//[c]Updates the enabling of the menu item
//[c]
private func update enabling (item: menu item)
def en = bool to gboolean (is enabled (cmd (item)))
gtk_widget_set_sensitive (menu item (item), en)
end
//[cf]
//[of]:command event (m, cmd)
//[c]Updates the menu according to the new state of the command.
//[c]
//[c] The following properties may have changed:
//[c] - caption
//[c] - enabled
//[c] - checked
//[c]
private func command event (item: menu item, cmd: command, event: command event)
switch type (event)
case command caption changed
update caption (item)
case command enabling changed
update enabling (item)
case command accelerator changed
if not nil (accel group (item))
def a = accelerator (event)
def key = key (a)
def flags = flags (a) : dword
if key <> 0
gtk_widget_remove_accelerator (
menu item (item),
accel group (item),
key: guint,
mask2 (flags))
end
a = accelerator (cmd)
key = key (a)
flags = flags (a) : dword
if key <> 0
gtk_widget_add_accelerator (
menu item (item),
"activate",
accel group (item),
key: guint,
mask2 (flags),
GTK_ACCEL_VISIBLE)
end
end
end
/*def flags = MF_BYCOMMAND | MF_STRING
if ~ is enabled (cmd)
flags |= MF_DISABLED | MF_GRAYED
end
if is checked (cmd)
flags |= MF_CHECKED
end
ModifyMenuA (
handle (peer (parent (item))),
id (cmd):UINT,
flags,
id (cmd):UINT,
caption (item))*/
end
//[c]
//[of]:mask (flags)
//[c]Registers a shortcut
//[c]
private func mask2 (flags: dword)
def mask = 0
if (flags & SHIFT) <> 0
mask |= GDK_SHIFT_MASK : int
end
if (flags & CTRL) <> 0
mask |= GDK_CONTROL_MASK : int
end
if (flags & ALT) <> 0
mask |= GDK_MOD1_MASK : int
end
return mask : GdkModifierType
end
//[cf]
//[cf]
//[cf]
//[of]:event handling
//[of]:activate (GtkMenuItem, menu item)
//[c]
private func activate (w: GtkMenuItem, m: menu item)
def cmd = cmd (m)
run (cmd)
end
//[cf]
//[of]:destroy (GtkMenuItem, menu item)
//[c]
private func destroy (w: GtkMenuItem, m: menu item)
menu item (m) = nil
end
//[cf]
//[cf]
//[cf]
//[of]:menu separator
//[of]:instance creation
//[of]:new menu separator
//[c]
private func new menu separator
def s = allocate memory (sizeof local menu separator): menu separator
id (s) = 0
is menu (s) = false
is separator (s) = true
// Creates the gtk object
def sep = gtk_separator_menu_item_new : GtkSeparatorMenuItem
gtk_widget_show (sep)
widget (s) = sep
g_signal_connect (
sep,
"destroy",
^destroy (GtkMenuItem, menu separator):GCallback,
s: gpointer)
return s
end
//[cf]
//[of]:delete (m)
//[c]
private func delete (s: menu separator)
def w = widget (s)
if not nil (w)
gtk_widget_destroy (w)
end
free memory (s)
end
//[cf]
//[cf]
//[of]:event handling
//[of]:destroy (GtkMenuItem, menu separator)
//[c]
private func destroy (w: GtkMenuItem, m: menu separator)
widget (m) = nil
end
//[cf]
//[cf]
//[cf]
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?