19928/jj_vision/interface/tools/tool.e
Jocelyn Fiat 6dde6425c2 init
2024-06-17 09:09:33 +02:00

751 lines
22 KiB
Plaintext

note
description: "[
Base class for all the tool windows. Has history list for
stepping forward and backward through the `viewable_items'
which have been displayed in the tool.
The {TOOL} is a EV_FRAME containing an EV_VERTICAL_BOX called
`main_container'. Into `main_container' is placed an EV_HORIZONTAL_BOX
serving as a toolbar called `title_bar'. (An EV_HORIZONTAL_BOX was
used instead of a EV_TOOL_BAR in order to add widgets other than
EV_TOOLBAR_BUTTONS to the toolbar, giving the desired look.) The
`title_bar' is built by adding text, buttons, spaces, other bars, etc
to it. Below the `title_bar' is added the `cell' from `split_manager'
which contains any {VIEW}s in the tool.
TNL = `tool_name_label' -- contains the `name' of the tool
HTB = `history_tool_bar` -- contains the forth and back buttons
TL = `target_label' -- shows the name of the object in the tool
TB = `tool_bar' -- clients add buttons here
UT = `user_text' -- an EV_LABEL allowed to expand (see `set_user_text')
RTB = `resize_tool_bar' -- contains the minimize/miximize and close buttons
FB = `forth_button' -- To go back in the history
BB = `back_button' -- to go forward in the history
xB = `maximize_button' or `restore_button'
X = `close_button'
`bar' = split_manager.bar -- any buttons produced by `split_manager' are here
|------------------------------ title bar -----------------------------------|
| | TNL | |--- HTB ---| | TL | |-- TB --| | `bar' | | UT | |--- RTB ---|
| | |BB| |FB| | | ... | | ... | | |xB| |X| |
|----------------------------------------------------------------------------|
| |
| |
| split_manager.cell |
| |
| |
|----------------------------------------------------------------------------|
The `bar' and `cell', both from `split_manager', will be empty because no
{VIEW}s have been added to the `split_manager'. Descendants should follow this
pattern as described in class {SPLIT_MANAGER}, redefining `initialize'.
feature initialize is
-- Set up the window.
-- Redefine to add the views to the window.
do
Precursor {TOOL}
split_manager.extend (view_one)
split_manager.extend (view_two)
end
Feature `initialize' above assumes two features, `view_one' and `view_two',
to be defined to return a descendant of {VIEW} and some effected EV_WIDGET.
]"
date: "30 Sep 03"
author: "Jimmy J. Johnson"
copyright: "Copyright 2012, Jimmy J. Johnson"
license: "Eiffel Forum License v2 (see forum.txt)"
URL: "$URL: file:///F:/eiffel_repositories/jj_vision/trunk/interface/tools/tool.e $"
date: "$Date: 2015-10-24 07:32:40 -0700 (Sat, 24 Oct 2015) $"
revision: "$Revision: 23 $"
class
TOOL
inherit
VIEW
undefine
-- default_create,
copy
redefine
create_interface_objects,
initialize,
add_actions,
set_target,
draw,
state
end
EV_FRAME
rename
object_id as ise_object_id
undefine
is_in_default_state
redefine
create_interface_objects,
initialize
end
PIXEL_BUFFERS
undefine
default_create,
copy
end
create
make
feature {NONE} -- Initialization
create_interface_objects
-- Create objects to be used by `Current' in `initialize'
-- Implemented by descendants to create attached objects
-- in order to adhere to void-safety due to the implementation bridge pattern.
do
Precursor {VIEW}
Precursor {EV_FRAME}
-- create history
create history_dropdown
create main_container
-- Create the action sequences
create maximize_actions
create close_actions
create restore_actions
-- Create the buttons
create title_bar
create tool_bar
create history_tool_bar
-- create user_text
create resize_tool_bar
create tool_name_label
create target_label
-- create history_combo -- see "fix me" comment before `update_history_combo' feature
create split_manager
-- Create buttons
create back_button
create forth_button
create maximize_button
create restore_button
create close_button
size_button := maximize_button
-- Set button attributes
back_button.set_pixmap (create {EV_PIXMAP}.make_with_pixel_buffer (Icon_back_color_buffer))
back_button.set_tooltip ("Back")
forth_button.set_pixmap (create {EV_PIXMAP}.make_with_pixel_buffer (Icon_forth_color_buffer))
forth_button.set_tooltip ("Forth")
maximize_button.set_pixmap (create {EV_PIXMAP}.make_with_pixel_buffer (Icon_maximize_color_buffer))
maximize_button.set_tooltip ("Maximize")
restore_button.set_pixmap (create {EV_PIXMAP}.make_with_pixel_buffer (Icon_restore_color_buffer))
restore_button.set_tooltip ("Restore")
close_button.set_pixmap (create {EV_PIXMAP}.make_with_pixel_buffer (Icon_close_color_buffer))
close_button.set_tooltip ("Close")
end
initialize
-- Build the interface for this window
-- Must create `view' before calling this.
local
hs: EV_HORIZONTAL_SEPARATOR
do
Precursor {EV_FRAME}
Precursor {VIEW}
-- tools.extend (Current)
-- Prevent the tool from holding more than one target, so
-- the history functions will work.
history_dropdown.set_parent_tool (Current)
target_label.set_minimum_width (Target_label_width)
-- view_manager.set_single_mode
-- split_manager.disable_mode_changes
-- Create the toolbar
build_tool_bars
build_title_bar
-- To get the tool bar look I used small 16x16 pixel icons.
-- The `title_bar' is an EV_HORIZONTAL_BOX which contains several
-- widets. These are a EV_LABLE, an EV_TOOL_BAR, another label
-- (which is allowed to expand), and finally another EV_TOOL_BAR
-- containing the `minimize_button' or the `restore_button' (depending
-- on `is_maximized') and the `close_button'.
main_container.extend (title_bar)
main_container.disable_item_expand (title_bar)
create hs
main_container.extend (hs)
main_container.disable_item_expand (hs)
main_container.extend (split_manager.cell)
extend (main_container)
set_minimum_height (100)
-- set_view (Default_view)
-- set_button_states
-- No, do not call `add_actions'; it is already called
-- from {VIEW}.`initialize' throught {SPLIT_VIEW}
-- add_actions
end
build_title_bar
-- Create the small title bar at top of tool
local
lab: EV_LABEL
do
-- Add the name of tool to the title bar
tool_name_label.set_text (generating_type.name)
title_bar.extend (tool_name_label)
title_bar.disable_item_expand (tool_name_label)
-- Add the forth and back buttons (in `history_tool_bar')
title_bar.extend (history_tool_bar)
title_bar.disable_item_expand (history_tool_bar)
-- Add a title to the tool
-- title_bar.extend (target_label)
-- title_bar.disable_item_expand (target_label)
-- Add a history list combo box
-- history_combo.disable_edit
-- title_bar.extend (history_combo) -- see "fix me" comment before `update_history_combo' feature
-- If use EV_COMBO_BOX the title bar must be bigger to
-- allow for `minimum_height' of the box.
-- Add the tool bar (to be used in descendants
title_bar.extend (tool_bar)
title_bar.disable_item_expand (tool_bar)
-- Put in a spacer to move the mode buttons to right
create lab.make_with_text (" ")
title_bar.extend (lab)
title_bar.disable_item_expand (lab)
-- Add the `bar' from `view_manager' here
title_bar.extend (split_manager.bar)
-- title_bar.disable_item_expand (split_manager.bar)
-- Add the maximize/minimize and hide buttons (in `resize_tool_bar')
title_bar.extend (resize_tool_bar)
title_bar.disable_item_expand (resize_tool_bar)
end
build_tool_bars
-- Create the tool bar.
local
vs: EV_VERTICAL_SEPARATOR
do
history_tool_bar.extend (back_button)
history_tool_bar.extend (forth_button)
history_tool_bar.extend (target_label)
-- create vs
-- history_tool_bar.extend (vs)
-- history_tool_bar.disable_item_expand (vs)
resize_tool_bar.extend (size_button)
resize_tool_bar.extend (close_button)
end
add_actions
-- Add functionality to the buttons.
do
Precursor {VIEW}
target_label.set_pebble_function (agent on_get_target)
-- Add actions to the buttons.
maximize_button.select_actions.extend (agent on_maximize)
restore_button.select_actions.extend (agent on_restore)
close_button.select_actions.extend (agent on_close)
back_button.select_actions.extend (agent on_back)
forth_button.select_actions.extend (agent on_forth)
-- Add actions to `history'
history_dropdown.select_actions.extend (agent on_history_item_selected)
target_label.pointer_button_press_actions.extend (agent on_target_label_selected)
-- target_label.drop_actions.extend (agent on_field_dropped_on_target_label)
-- see "fix me" comment before `update_history_combo' feature
-- history_combo.select_actions.extend (agent on_history_selected)
-- Add actions to update any views contained in this tool
-- No. Don't do this as the tool may contain views which only want to handle a part of the viewable.
-- Passing the wrong kind breaks the contract. Make each descendent descide what to pass to its children views.
-- viewable_added_action_sequence.extend (agent on_viewable_added)
end
feature -- Access
tool_bar: EV_HORIZONTAL_BOX --EV_TOOL_BAR
-- Available for adding new buttons in descendants.
state: TOOL_STATE
-- Snapshot of the current settings of Current
do
create Result.make (Current)
end
feature -- Element change
set_target (a_target: like target)
-- Change the value of `target' and add it to the `object_set' (the set
-- of objects contained in this view. The old target is removed from
-- the set.
do
Precursor {VIEW} (a_target)
update_history
-- if target_imp /= a_target then
-- Precursor {VIEW} (a_target)
---- add_object (a_target.target_label_field)
---- tool_label.set_accept_cursor (a_viewable.accept_cursor)
---- tool_label.set_deny_cursor (a_viewable.deny_cursor)
-- update_history
-- draw
-- end
end
-- set_user_text (a_string: STRING)
-- -- Change the `user_text'
-- do
-- user_text.set_text (a_string)
-- end
feature {SPLIT_MANAGER, HISTORY_DROPDOWN} -- Access
tool_name_label: EV_LABEL
-- String in top left of toolbar to display the name of the tool.
target_label: EV_LABEL
-- String in the bar to display the name of the `target'.
maximize_actions: EV_NOTIFY_ACTION_SEQUENCE
-- Actions to be performed when the tool is maximized.
close_actions: EV_NOTIFY_ACTION_SEQUENCE
-- Actions to be performed when the tool is closed.
restore_actions: EV_NOTIFY_ACTION_SEQUENCE
-- Actions to be performed when the tool is restored.
feature -- Element change
-- set_user_text (a_text: STRING_8)
-- -- Change the `user_text' that is displayed in the title bar.
-- do
-- user_text.set_text (a_text)
-- end
feature -- Status report
is_maximized: BOOLEAN
-- Is the tool in a maximized state?
is_resizable: BOOLEAN
-- Is the tool resizable? (E.g. is the `resize_tool_bar' visible?)
do
Result := resize_tool_bar.is_displayed
end
-- is_destroyed: BOOLEAN
-- -- Is `Current' no longer usable?
-- do
-- Result := not tools.has (Current) and Precursor {EV_FRAME}
-- end
feature -- Status setting
enable_resize
-- Allow the `resize_tool_bar' to show.
do
resize_tool_bar.show
end
disable_resize
-- Hide the `resize_tool_bar'.
do
resize_tool_bar.hide
end
enable_history
-- Make the `history_tool_bar' visible
do
history_tool_bar.show
-- target_label.show
end
disable_history
-- Make the `history_tool_bar' NOT visible
do
history_tool_bar.hide
-- target_label.hide
end
feature -- Basic operations
draw
-- Builds the string shown at top of the tool in `viewable_label'
-- using the id of the object.
local
n: STRING
s: STRING
f: EV_FONT
i: INTEGER
w: INTEGER -- for testing
do
if is_view_empty then
n := "Empty"
else
if attached {EDITABLE} target as e then
n := e.display_name
else
n := target.generating_type
end
end
f := target_label.font
create s.make (0)
from i := 1
until i > n.count or else f.string_width (s) >= Target_label_width
loop
w := f.string_width (s)
s.append_character (n.item (i))
i := i + 1
end
if f.string_width (s) > Target_label_width then
s.remove_tail (1)
end
target_label.set_text (s)
target_label.set_tooltip (n)
set_button_states
end
feature {NONE} -- Actions
-- on_field_dropped_on_target_label (a_field: STRING_FIELD) is
-- -- React to a drop of `a_field' onto the `target_label'.
-- require
-- field_exists: a_field /= Void
-- do
-- target.set_target_label_field (a_field)
-- draw_views (target.target_label_field)
-- end
on_target_label_selected (a_x, a_y, a_button: INTEGER;
a_x_tilt, a_y_tilt, a_pressure: DOUBLE;
a_screen_x, a_screen_y: INTEGER)
--
do
if a_button = 1 then
history_dropdown.show
end
end
on_history_item_selected
-- React to an item selection from the `history_dropdown'.
do
set_target (selected_history_item_target)
end
on_get_target: like target
-- Used as agent for `target_label.get_pebble_function' because
-- an attribute cannot be used as an agent
do
Result := target
end
-- see "fix me" comment before `update_history_combo' feature
-- on_history_selected is
-- -- Handle an item select in the history combo box
-- require
-- history_exists: history /= Void
-- local
-- cli: CLUSTER_LIST_ITEM
-- do
-- cli ?= history_combo.selected_item
-- check
-- cli_not_void: cli /= Void -- because only CLUSTER_LIST_ITEMS should be in list
-- end
-- set_cluster (cli.cluster)
-- end
on_back
-- Handle a go back request (from button or menu).
require
history_exists: history_dropdown /= Void
history_can_go_back: not history_dropdown.is_off and then not history_dropdown.is_before
local
v: HISTORY_ITEM
do
history_dropdown.back
v := history_dropdown.item
check attached {like target} v.target as t then
set_target (t)
end
set_button_states
end
on_forth
-- Handle a go forth request (from button or menu).
require
history_exists: history_dropdown /= Void
history_can_go_forth: not history_dropdown.is_off and then not history_dropdown.is_after
local
v: HISTORY_ITEM
do
history_dropdown.forth
v := history_dropdown.item
check attached {like target} v.target as t then
set_target (t)
end
set_button_states
end
on_maximize
-- React to a request (button or menu) to "maximize" by performing
-- the actions in `maximize_actions'.
require
resizing_allowed: is_resizable
do
maximize_actions.call ([])
end
on_restore
-- React to a request (button or menu) to "maximize" by performing
-- the actions in `maximize_actions'.
require
resizing_allowed: is_resizable
do
restore_actions.call ([])
end
on_close
-- React to a close request by executing the `close_actions'.
require
resizing_allowed: is_resizable
do
close_actions.call ([])
end
feature {SPLIT_MANAGER, TOOL_STATE} -- Actions
maximize
-- Put window in maximized state
require
resizing_allowed: is_resizable
do
is_maximized := True
if not (size_button = restore_button) then
resize_tool_bar.go_i_th (resize_tool_bar.index_of (size_button, 1))
resize_tool_bar.replace (restore_button)
size_button := restore_button
end
close_button.disable_sensitive
end
restore
-- Put window back in default state
require
-- resizing_allowed: is_resizable
do
is_maximized := False
if not (size_button = maximize_button) then
resize_tool_bar.go_i_th (resize_tool_bar.index_of (size_button, 1))
resize_tool_bar.replace (maximize_button)
size_button := maximize_button
end
close_button.enable_sensitive
end
close_button: EV_TOOL_BAR_BUTTON
-- Button containing an "X" icon
maximize_button: EV_TOOL_BAR_BUTTON
-- Button which parent can access intended
-- to be used to maximize the tool.
restore_button: EV_TOOL_BAR_BUTTON
-- Button which parent can access intended
-- to be used to normalize (restore) the tool.
feature {NONE} -- Implementation
update_history
-- Update the history list.
require
target_exists: target /= Void
local
found: BOOLEAN
v: HISTORY_ITEM
oldest_v: HISTORY_ITEM
do
-- if not history.has (viewable) then -- not needed if history is a SET
-- does history have viewable? Must do a search because list items
from history_dropdown.start
until found or else history_dropdown.is_exhausted
loop
v := history_dropdown.item
if v.is_simular (new_history_item) then
found := True
else
history_dropdown.forth
end
end
if found then
-- leave list as is but change time stamp of found item
v := history_dropdown.item
v.reset_time_stamp
else
-- not found so must add a new one
v := new_history_item
history_dropdown.extend (v)
if history_dropdown.count > maximum_history_items then
-- find oldest item in list and remove it
oldest_v := history_dropdown.first
from history_dropdown.start
until history_dropdown.is_exhausted
loop
v := history_dropdown.item
if v.time_stamp < oldest_v.time_stamp then
oldest_v := history_dropdown.item
end
history_dropdown.forth
end
history_dropdown.start
history_dropdown.prune (oldest_v)
end
history_dropdown.start
history_dropdown.search (v)
-- Display a string describing the target
target_label.set_text (v.target.generating_type.name + " " + v.time_stamp.as_string)
check
not_off: not history_dropdown.is_off -- because just inserted it
end
end
-- update_history_combo -- see "fix me" comment before `update_history_combo' feature
-- set_button_states
-- end
ensure
proper_histroy_count: history_dropdown.count <= maximum_history_items
end
-- Fix me!!!
-- `update_history_combo' is a problem.
-- Line "history_combo.wipe_out" causes a system crash, perhaps the screen
-- objects are not getting destroyed? Tried destroying each item in combo
-- but that did not help.
-- Also, can't seem to set the text; get an infinate loop?
-- Besides, the combo box is too tall; it make the TOOL's toolbar and buttons
-- too big, so commenting it out.
-- update_history_combo is
-- -- Put the history items into the `history_combo' box
-- local
-- cli: CLUSTER_LIST_ITEM
-- pos: CURSOR
-- c: CLUSTER
-- do
-- history_combo.wipe_out
-- pos := history.cursor
-- c := history.item.cluster
-- from history.start
-- until history.exhausted
-- loop
-- if history.item.cluster /= c then
-- create cli.make (history.item.cluster)
-- history_combo.extend (cli)
-- end
-- history.forth
-- end
-- history.go_to (pos)
-- history_combo.enable_edit -- so set_text will work
-- history_combo.set_text (history.item.cluster.id)
-- history_combo.disable_edit
-- end
set_button_states
-- Set the states of the back and forth buttons.
do
if history_dropdown.is_empty or history_dropdown.is_first or history_dropdown.is_before then
back_button.disable_sensitive
else
back_button.enable_sensitive
end
if history_dropdown.is_empty or history_dropdown.is_last or history_dropdown.is_after then
forth_button.disable_sensitive
else
forth_button.enable_sensitive
end
if history_dropdown.is_empty then
target_label.disable_sensitive
else
target_label.enable_sensitive
end
end
main_container: EV_VERTICAL_BOX
-- Holds the other widgets in the TOOL.
title_bar: EV_HORIZONTAL_BOX
-- Holds the name of tool, `history_tool_bar', and `resize_tool_bar'.
history_tool_bar: EV_HORIZONTAL_BOX --EV_TOOL_BAR
-- The toolbar with the forth, back and posibly history buttons.
-- user_text: EV_LABEL
-- -- Text settable by `set_user_text'
resize_tool_bar: EV_TOOL_BAR
-- Tool bar to hold resize and close buttons
feature {NONE} -- Implementation
forth_button: EV_BUTTON --EV_TOOL_BAR_BUTTON
-- Button containing go back icon
back_button: EV_BUTTON --EV_TOOL_BAR_BUTTON
-- Button containing go forth icon
size_button: EV_TOOL_BAR_BUTTON
-- Button containing maximize or restore icon
-- history_combo: EV_COMBO_BOX -- see "fix me" comment before `update_history_combo' feature
-- To pull down a history list
maximum_history_items: INTEGER = 5
-- Number of items to keep in history list
feature {HISTORY_DROPDOWN} -- Implementation
history_dropdown: HISTORY_DROPDOWN
-- A dropdown-like box containing the clusters previously targetted
-- in this tool from which selections can be made to retarget the tool.
new_history_item: HISTORY_ITEM
-- Helper routine called by `update_history' when it needs to
-- create a new time-stamped viewable for placement in the `history'.
-- Made a seperate routine because descendents may want to store
-- other types of items in the history list.
do
create Result.make (target)
end
selected_history_item_target: like target
-- The item from the `history_dropdown' typecast to `target'
do
check attached {HISTORY_ITEM} history_dropdown.selected_item as hi then
check attached {like target} hi.target as t then
Result := t
end
end
ensure
Result_exists: Result /= Void
end
feature {NONE} -- Implementation
split_manager: SPLIT_MANAGER
-- Controls placement of sub-windows
--feature {TOOL} -- Implementation
-- tools: LINKED_SET [TOOL]
-- -- Keeps track of all the TOOLs in the system
-- once
-- create Result.make
-- end
feature {NONE} -- Constants
Target_label_width: INTEGER = 100
-- Sets the size of the `target_label' in pixels.
invariant
close_button_exists: close_button /= Void
restore_button_exists: restore_button /= Void
maximize_button_exists: maximize_button /= Void
-- label_clickable_when: history.is_empty implies not object_label.is_sensitive
end