19928/jj_vitp/Interface/widgets/vitp_widget.e
Jocelyn Fiat 6dde6425c2 init
2024-06-17 09:09:33 +02:00

986 lines
26 KiB
Plaintext

note
description: "[
Root class for widgets in VITP where `item' represents some {VITP_ITEM}.
This also has features for aligning a widget with another.
]"
author: "Jimmy J. Johnson"
deferred class
VITP_WIDGET
inherit
-- EV_WIDGET
JJ_MODEL_WORLD_VIEW
-- See newgroup message 20398. Concrete descendants must
-- re-implement `new_filled_list' (from ARRAYED_LIST) as:
-- new_filled_list (n: INTEGER): like Current
-- -- New list with `n' elements.
-- do
-- create Result.make (n)
-- end
-- undefine
-- new_filled_list
redefine
create_interface_objects,
initialize,
set_target,
set_dimming_level,
target_imp,
add_actions,
new_filled_list
-- Let's try redefining with an empty body; this feature
-- may be inapplicable anyway.
-- select
-- default_create
end
-- DIMABLE
-- rename
-- default_create as initialize_dimable
-- redefine
-- set_dimming_level
-- end
FONT_AND_COLOR_CONSTANTS
export
{NONE}
all
undefine
default_create
end
feature {NONE} -- Initialization
create_interface_objects
-- Initialize attributes
require else
not_initialized: not is_initialized
local
i: INTEGER
c: EV_COORDINATE
do
accept_cursor := Default_accept_cursor
deny_cursor := Default_accept_cursor
foreground_color := Black
create font
create text_group
create name_mt
create dot
Precursor {JJ_MODEL_WORLD_VIEW}
end
frozen initialize
-- Set up the widgets in Current.
require else
not_initialized: not is_initialized
do
-- set_font (Default_font)
-- initialize_defining_figure
extend_widgets
build_widgets
set_fonts_and_colors
position_widgets
set_widget_order
-- add_actions
dot.set_line_width (10)
-- The Precursor from {VIEW} calls `add_actions'
Precursor {JJ_MODEL_WORLD_VIEW}
set_pebble (target)
is_initialized := True
end
extend_widgets
-- Put widgets into Current. This cannot be done
-- in `create_interface_object', because cannot call
-- `extend' feature until all objects [in descendants]
-- are also created.
do
extend (dot)
extend (text_group)
text_group.extend (name_mt)
-- Cannot put `jj_defining_figure' in yet, because
-- descendants may not have finished creation and
-- `jj_defining_figure' is self-initializing.
-- extend (jj_defining_figure)
end
build_widgets
-- Now that widgets were created in `create_interface_objects'
-- and added to Current in `extend_widgets', build up the
-- widgets by adding internal structure to each widget.
do
end
set_fonts_and_colors
-- Set the default fonts for any text widgets and set
-- the default colors for any contained widgets.
do
end
position_widgets
-- Move Current and contained widgets to correct
-- location and set their sizes
require
not_initialized: not is_initialized
do
-- Center text on Current
text_group.set_x_y (x, y)
end
set_widget_order
-- Ensure the widgets are ordered properly
-- (i.e. whose on top?)
do
bring_to_front (text_group)
bring_to_front (dot)
-- Next line is okay, I think
extend (jj_defining_figure)
bring_to_front (jj_defining_figure)
end
add_actions
-- Add actions to Current
do
check not is_view_initialized then
-- pointer_enter_actions.extend (agent on_pointer_enter)
-- pointer_leave_actions.extend (agent on_pointer_leave)
-- pointer_motion_actions.extend (agent on_pointer_motion)
-- pointer_button_press_actions.extend (agent on_button_pressed)
-- pointer_double_press_actions.extend (agent on_pointer_double_pressed)
-- pointer_button_release_actions.extend (agent on_button_released)
-- pointer_motion_actions.extend (agent on_pointer_motion)
-- pointer_enter_actions.extend (agent on_pointer_enter)
-- pointer_leave_actions.extend (agent on_pointer_leave)
end
Precursor {JJ_MODEL_WORLD_VIEW}
end
-- build_bounding_figure
-- -- Add points to the `jj_bounding_figure'.
-- -- The default builds a polygon from the `bounding_box'.
-- require
-- not_initialized: not is_initialized
-- local
-- bb: like bounding_box
-- do
-- jj_bounding_figure.set_point_count (4)
-- bb := bounding_box
-- jj_bounding_figure.set_i_th_point_position (1, bb.lower_left.x, bb.lower_left.y)
-- jj_bounding_figure.set_i_th_point_position (2, bb.upper_left.x, bb.upper_left.y)
-- jj_bounding_figure.set_i_th_point_position (3, bb.upper_right.x, bb.upper_right.y)
-- jj_bounding_figure.set_i_th_point_position (4, bb.lower_right.x, bb.lower_right.y)
-- bring_to_front (jj_bounding_figure)
-- jj_bounding_figure.hide
-- jj_bounding_figure.enable_closed
-- ensure
-- has_enough_points: jj_bounding_figure.point_count >= 1
-- has_bounding_figure: has (jj_bounding_figure)
-- end
set_initialized
-- Make `is_initialized'
do
is_initialized := true
end
feature -- Access
game: VITP_GAME
-- The game for which this widget provides an interface.
do
Result := target.game
end
foreground_color: EV_COLOR
-- Can be used to `paint' contained widgets
-- background_color: EV_COLOR
-- -- Can be used to `paint' contained widgets.
-- defined in EV_MODEL_WORLD
font: EV_FONT
-- The base font from which the size, weight, etc
-- of the fonts for any texts in Current can be based.
dot: EV_MODEL_DOT
-- A point on Current used for positioning child widgets
jj_defining_figure: EV_MODEL_CLOSED
-- A shape to mark the boundary of Current, used
-- to determine if widgets overlap or depart an area.
attribute
create {EV_MODEL_RECTANGLE} Result.make_with_points (bounding_box.upper_left, bounding_box.lower_right)
Result.set_line_width (5)
end
midpoint: EV_COORDINATE
-- The point that is the center of the `jj_bounding_figure'
-- relative to Current's containing group
local
p: EV_COORDINATE
mid: EV_COORDINATE
do
p := point_relative
mid := points_middle (min_values, max_values)
create Result.make_precise (p.x + mid.x, p.y + mid.y)
end
feature -- Element change
set_target (a_item: like target)
-- Associate `a_item' with Current.
local
s, s1, s2: STRING
pos: INTEGER
do
Precursor {JJ_MODEL_WORLD_VIEW} (a_item)
-- Set text, handling a couple of {PORT} names specially
if target = game.Pearl_harbor or
target = game.Johnston_island or
target = game.New_hebrides or
target = game.dutch_harbor or
target = game.Andaman_islands then
-- split into two lines
s := target.name
pos := s.index_of (' ', 1)
s1 := s.substring (1, pos - 1)
s2 := s.substring (pos + 1, s.count)
-- Add spaces to better center text on circles
if target = game.pearl_harbor or target = game.dutch_harbor then
s1 := " " + s1
elseif target = game.johnston_island then
s2 := " " + s2
elseif target = game.new_hebrides then
s1 := " " + s1
elseif target = game.andaman_islands then
s2 := " " + s2
end
name_mt.set_text (s1 + "%N" + s2)
else
name_mt.set_text (target.name)
end
-- Set the color of and draw the contained widgets
paint
end
set_foreground_color (a_color: EV_COLOR)
-- Change the color in which the text is drawn
require
color_exists: a_color /= Void
do
foreground_color := a_color
paint
end
-- set_font (a_font: EV_FONT)
-- -- Change the appearance of the `font' from which
-- -- the fonts (height, weight, etc.) of any text
-- -- widgets in Current can be based.
-- do
-- font := a_font
-- name_mt.set_font (font)
-- end
feature -- Basic operations
set_dimming_level (a_level: INTEGER)
-- Change the `dimming_level'
do
Precursor {JJ_MODEL_WORLD_VIEW} (a_level)
from start
until exhausted
loop
if attached {VITP_WIDGET} item as v then
-- io.put_string (" VITP_WIDGET.set_dimming_level - widget is a {" + v.generating_type + "} %N" )
v.set_dimming_level (a_level)
end
forth
end
paint
end
paint
-- Set the color of items in this widget and hide/show figures
do
if is_defining_figure_shown then
jj_defining_figure.show
else
jj_defining_figure.hide
end
name_mt.set_foreground_color (adjusted_color (foreground_color))
end
-- center_on (a_x, a_y: INTEGER_32)
-- -- Move Current so its center point is on (a_x, a_y).
-- local
-- bb: EV_RECTANGLE
-- do
-- bb := bounding_box
-- set_x_y (a_x - (bb.x + bb.width // 2), a_y - (bb.y + bb.height // 2))
-- end
center_on_point (a_point: EV_COORDINATE)
-- Transform Current so its center point is on `a_point'
require
point_exists: a_point /= Void
local
t: EV_MODEL_TRANSFORMATION
ax, ay: REAL_64
bb: EV_RECTANGLE
do
bb := bounding_box
ax := a_point.x_precise - (bb.x + bb.width / 2)
ay := a_point.y_precise - (bb.y + bb.height / 2)
create t.make_id
t.translate (ax, ay)
transform (t)
end
center_on_dot (a_dot: EV_MODEL_DOT)
-- Place the center of `a_widget' on `a_dot'
require
dot_exists: a_dot /= Void
local
bb: EV_RECTANGLE
cx, cy: REAL_64
dif_x, dif_y: REAL_64
t: EV_MODEL_TRANSFORMATION
do
bb := bounding_box
cx := bb.width / 2
cy := bb.height / 2
dif_x := (bb.x + cx) - a_dot.point.x_precise
dif_y := (bb.y + cy) - a_dot.point.y_precise
-- dif_x := (bb.x + cx) - dot.point_x
-- dif_y := (bb.y + cy) - dot.point_y
create t.make_zero
t.translate (-dif_x, -dif_y)
transform (t)
end
center_on_origin
-- Place the center of the widget at (0,0)
local
t: EV_MODEL_TRANSFORMATION
ax, ay: REAL_64
bb: EV_RECTANGLE
do
bb := bounding_box
ax := bb.x + bb.width / 2
ay := bb.y + bb.height / 2
create t.make_id
t.translate (-ax, -ay)
transform (t)
end
center_widget_on_dot (a_widget: EV_MODEL; a_dot: EV_MODEL_DOT)
-- Place the center of `a_widget' on `a_dot'
local
bb: EV_RECTANGLE
cx, cy: REAL_64
dif_x, dif_y: REAL_64
t: EV_MODEL_TRANSFORMATION
do
bb := a_widget.bounding_box
cx := bb.width / 2
cy := bb.height / 2
dif_x := (bb.x + cx) - dot.point.x_precise
dif_y := (bb.y + cy) - dot.point.y_precise
create t.make_zero
t.translate (-dif_x, -dif_y)
a_widget.transform (t)
end
center_widget_on_other (a_widget: EV_MODEL; a_other: EV_MODEL)
-- Place the center of `a_widget' on `a_other'
local
bb, bb_other: EV_RECTANGLE
bb_center_x, bb_center_y: REAL_64
bb_other_center_x, bb_other_center_y: REAL_64
cx, cy: REAL_64
dif_x, dif_y: REAL_64
t: EV_MODEL_TRANSFORMATION
do
bb := a_widget.bounding_box
bb_other := a_other.bounding_box
bb_center_x := bb.left + bb.width / 2
bb_center_y := bb.top + bb.height / 2
bb_other_center_x := bb_other.left + bb_other.width / 2
bb_other_center_y := bb_other.top + bb_other.height / 2
dif_x := bb_other_center_x - bb_center_x
dif_y := bb_other_center_y - bb_center_y
-- cx := bb.width / 2
-- cy := bb.height / 2
-- dif_x := (bb.x + cx) - dot.point.x_precise
-- dif_y := (bb.y + cy) - dot.point.y_precise
-- dif_x := (bb.x + cx) - a_other.point_array.item (0).x_precise
-- dif_y := (bb.x + cx) - a_other.point_array.item (0).x_precise
create t.make_zero
t.translate (dif_x, dif_y)
a_widget.transform (t)
-- Check for identical centers
bb := a_widget.bounding_box
bb_other := a_other.bounding_box
bb_center_x := bb.left + bb.width / 2
bb_center_y := bb.top + bb.height / 2
bb_other_center_x := bb_other.left + bb_other.width / 2
bb_other_center_y := bb_other.top + bb_other.height / 2
dif_x := bb_other_center_x - bb_center_x
dif_y := bb_other_center_y - bb_center_y
end
translate_widget (a_widget: EV_MODEL; a_x, a_y: INTEGER_32)
-- Move `a_widget' in x and y directions.
local
t: EV_MODEL_TRANSFORMATION
do
create t.make_zero
t.translate (a_x, a_y)
-- a_widget.transform (t)
a_widget.set_x_y (a_widget.x + a_x, a_widget.y + a_y)
end
rotate_widget (a_widget: EV_MODEL; a_degrees: REAL_64)
-- Rotate `a_widget' `a_degrees' clockwise.
local
rad: REAL_64
do
rad := degrees_to_radians (a_degrees)
a_widget.rotate (rad)
end
scale_widget (a_widget: EV_MODEL; a_scale: REAL_64)
-- Resize `a_widget' by `a_scale' factor.
do
a_widget.scale (a_scale)
end
align_midpoints (a_other: VITP_WIDGET)
-- Move Current so its `midpoint' is over the `midpoint' of `a_other'
local
t: EV_MODEL_TRANSFORMATION
po: EV_COORDINATE
do
po := points_offset (midpoint, a_other.midpoint)
create t.make_zero
t.translate (po.x_precise, po.y_precise)
transform (t)
end
align_midpoints_with_offset (a_other: VITP_WIDGET; a_x_offset, a_y_offset: REAL_64)
-- Move Current so its `midpoint' is offset from the `midpoint'
-- of `a_other' by the offsets (as percentages of the size of
-- Current in that direction).
local
t: EV_MODEL_TRANSFORMATION
s: EV_COORDINATE
xx, yy: REAL_64
do
s := a_other.size_values
align_midpoints (a_other)
xx := s.x_precise * a_x_offset
yy := s.y_precise * a_y_offset
create t.make_zero
t.translate (xx, yy)
transform (t)
end
align_vertical (a_other: VITP_WIDGET)
-- Move Current horizontally until it's `midpoint.x' is aligned
-- with the `midpoint.x' of `a_other'.
local
t: EV_MODEL_TRANSFORMATION
po: EV_COORDINATE
do
po := points_offset (midpoint, a_other.midpoint)
create t.make_zero
t.translate (po.x_precise, 0.0)
transform (t)
end
align_horizontal (a_other: VITP_WIDGET)
-- Move Current vertically until it's `midpoint.y' is aligned
-- with the `midpoint.y' of `a_other'.
local
t: EV_MODEL_TRANSFORMATION
po: EV_COORDINATE
do
po := points_offset (midpoint, a_other.midpoint)
create t.make_zero
t.translate (0.0, po.y_precise)
transform (t)
end
align_lefts (a_other: VITP_WIDGET)
-- Move Current so its left side is aligned with
-- the left side of `a_other'
local
t: EV_MODEL_TRANSFORMATION
c, o: REAL_64 -- current's value; other's value
do
c := min_values.x
o := a_other.min_values.x
create t.make_zero
t.translate (o - c, 0.0)
transform (t)
end
align_rights (a_other: VITP_WIDGET)
-- Move Current so its right side is aligned with
-- the right side of `a_other'
local
t: EV_MODEL_TRANSFORMATION
c, o: REAL_64
do
c := max_values.x
o := a_other.max_values.x
create t.make_zero
t.translate (o - c, 0.0)
transform (t)
end
align_tops (a_other: VITP_WIDGET)
-- Move Current so its top side is aligned with
-- the top side of `a_other'
local
t: EV_MODEL_TRANSFORMATION
c, o: REAL_64
do
c := max_values.y
o := a_other.max_values.y
create t.make_zero
t.translate (0.0, o - c)
transform (t)
end
align_bottoms (a_other: VITP_WIDGET)
-- Move Current so its bottom side is aligned with
-- the bottom side of `a_other'
local
t: EV_MODEL_TRANSFORMATION
c, o: REAL_64
do
c := min_values.y
o := a_other.min_values.y
create t.make_zero
t.translate (o - c, 0.0)
transform (t)
end
align_left_to_others_right (a_other: VITP_WIDGET)
-- Move Current so its left side is aligned with the
-- left side of `a_other'
local
t: EV_MODEL_TRANSFORMATION
o, c: REAL_64
do
c := min_values.x
o := a_other.max_values.x
create t.make_zero
t.translate (o - c, 0.0)
transform (t)
end
align_right_to_others_left (a_other: VITP_WIDGET)
-- Move Current so its right side is aligned with the
-- left side of `a_other'
local
t: EV_MODEL_TRANSFORMATION
c, o: REAL_64
do
c := max_values.x
o := a_other.min_values.x
create t.make_zero
t.translate (o - c, 0.0)
transform (t)
end
align_top_to_others_bottom (a_other: VITP_WIDGET)
-- Move Current so its top side is aligned with the
-- bottom side of `a_other'
local
t: EV_MODEL_TRANSFORMATION
c, o: REAL_64
do
c := min_values.y
o := a_other.max_values.y
create t.make_zero
t.translate (0.0, o - c)
transform (t)
end
align_bottom_to_others_top (a_other: VITP_WIDGET)
-- Move Current so its top side is aligned with the
-- bottom side of `a_other'
local
t: EV_MODEL_TRANSFORMATION
c, o: REAL_64
do
c := min_values.y
o := a_other.max_values.y
create t.make_zero
t.translate (o - c, 0.0)
transform (t)
end
feature -- Actions
-- timer: TIME
-- on_pointer_enter
-- -- React to the mouse pointer entering Current
-- do
-- io.put_string ("VITP_WIDGET.on_enter " + vitp_item.name + "%N")
-- -- Start timer; after delay with no movement show status dialog
-- end
-- on_pointer_leave
-- -- React to the mouse pointer leaving Current
-- do
-- io.put_string ("VITP_WIDGET.on_leave " + vitp_item.name + "%N")
-- end
-- on_pointer_motion (ax, ay: INTEGER; ax_tilt, ay_tilt, apressure: DOUBLE;
-- a_screen_x, a_screen_y: INTEGER)
-- -- React to the mouse moving within Current
-- do
-- io.put_string ("VITP_WIDGET.on_move " + vitp_item.name + "%N")
-- end
feature -- Status report
is_initialized: BOOLEAN
-- Has Curent been initialized? (I.e. all all widgets built?)
-- Used to prevent calling `initialize' more than once.
is_defining_figure_shown: BOOLEAN
-- Can be used by descendants to determine if the `jj_bounding_figure'
-- should be visible or not.
feature -- Query
contains_point (a_point: EV_COORDINATE): BOOLEAN
-- Is `a_point' on or in Current's `jj_defining_figure'?
local
pts: SPECIAL [EV_COORDINATE] -- for convenience
i, j: INTEGER
do
-- pts := jj_bounding_figure.point_array
-- -- Remember SPECIAL is zero-based
-- from
-- i := 0
-- j := pts.count - 1
-- until i > pts.count - 1
-- loop
-- if ( ((pts[i].y_precise >= a_point.y_precise) /= (pts[j].y_precise >= a_point.y_precise)) and
-- (a_point.x_precise <= (pts[j].x_precise - pts[i].x_precise) *
-- (a_point.y_precise - pts[i].y_precise) /
-- (pts[j].y_precise - pts[i].y_precise) + pts[i].x_precise) ) then
-- Result := not Result
-- end
-- j := i
-- i := i + 1
-- end
Result := jj_defining_figure.position_on_figure (a_point.x, a_point.y)
end
overlaps (a_other: VITP_WIDGET): BOOLEAN
-- Does Current occupy any space occupied by a_other
local
pts: SPECIAL [EV_COORDINATE]
i: INTEGER
do
if Current /= a_other then
pts := jj_defining_figure.point_array
-- Remember SPECIAL is zero-based
from i := 0
until i > pts.count - 1 or Result
loop
Result := a_other.contains_point (pts[i])
i := i + 1
end
-- Check the other way around
if not Result then
pts := a_other.jj_defining_figure.point_array
from i := 0
until i > pts.count - 1 or Result
loop
Result := contains_point (pts[i])
i := i + 1
end
end
end
end
touches (a_other: VITP_WIDGET): BOOLEAN
-- Does Current touch `a_other'?
do
end
is_touched_by (a_other: VITP_WIDGET): BOOLEAN
-- Is Current touched by `a_other'?
do
end
contains (a_other: VITP_WIDGET): BOOLEAN
-- Does Current contain *all* of `a_other'?
do
end
is_contained_by (a_other: VITP_WIDGET): BOOLEAN
-- Is *all* of Current within `a_other'?
do
end
diverges_from (a_other: VITP_WIDGET): BOOLEAN
-- Does Current `intersects' `a_other' while having any
-- point outside `a_other'
do
end
feature {NONE} -- Inapplicable
new_filled_list (n: INTEGER): like Current
-- Redefined to get past void-safety issues
do
check
do_not_call: False then
-- Because this was redefined to appease void-safety, nothing else.
end
end
feature -- Actions
activate_drop_action
-- Allow Current to react to the drop of a unit, moving
-- that unit to the `location' in Current.
do
drop_actions.extend (drop_unit_agent)
end
deactivate_drop_action
-- Remove the agent added by `activate_drop_actions
do
drop_actions.start
drop_actions.prune (drop_unit_agent)
end
frozen drop_unit_agent: PROCEDURE [TUPLE [ATTACK_UNIT]]
-- Create an agent out of `on_drop_unit' which will be added
-- to Current when a pick is started and the Sequence of Play
-- allows for the unit to be dropped here.
once ("OBJECT")
Result := agent on_drop_unit
end
on_drop_unit (a_unit: ATTACK_UNIT)
-- Move `a_unit' to `locaiton'
do
print ("{LOCATION_WIDGET}.on_drop_unit: dropped " + a_unit.name + " on " + target.name + "%N")
end
feature {NONE} -- Implementation (actions)
on_button_pressed (ax: INTEGER; ay: INTEGER; a_button: INTEGER; x_tilt: DOUBLE; y_tilt: DOUBLE;
pressure: DOUBLE; a_screen_x: INTEGER; a_screen_y: INTEGER)
-- Notify `board_world' that Current was clicked
-- This allows the `board_world' to handle the click *and* to know the
-- widget on which the click occurred.
do
io.put_string ("VITP_WIDGET.on_button_pressed on " + target.name + "%N")
-- if attached board_world as bw then
-- bw.on_notify_button_pressed (Current, ax, ay, a_button)
-- end
end
-- on_pointer_double_pressed (ax: INTEGER; ay: INTEGER; a_button: INTEGER; x_tilt: DOUBLE; y_tilt: DOUBLE;
-- pressure: DOUBLE; a_screen_x: INTEGER; a_screen_y: INTEGER)
-- -- Notify `board_world' that Current was double-clicked
-- -- This allows the `board_world' to handle the click *and* to know the
-- -- widget on which the click occurred.
-- do
-- if attached board_world as bw then
-- bw.on_notify_button_double_pressed (Current, ax, ay, a_button)
-- end
-- end
-- on_button_released (ax: INTEGER; ay: INTEGER; a_button: INTEGER; x_tilt: DOUBLE; y_tilt: DOUBLE;
-- pressure: DOUBLE; a_screen_x: INTEGER; a_screen_y: INTEGER)
-- -- Notify `board_world' that `a_button' was released on it
-- do
-- if attached board_world as bw then
-- bw.on_notify_button_released (Current, ax, ay, a_button)
-- end
-- end
-- on_pointer_motion (ax: INTEGER; ay: INTEGER; x_tilt: DOUBLE; y_tilt: DOUBLE;
-- pressure: DOUBLE; a_screen_x: INTEGER; a_screen_y: INTEGER)
-- -- Notify `board_world' that mouse was moved on Current
-- local
-- c: EV_COORDINATE
-- do
-- if attached board_world as bw then
-- bw.on_notify_pointer_motion (Current, ax, ay)
-- end
-- end
-- on_pointer_enter
-- -- React to the mouse entering the `dot'
-- do
-- if attached board_world as bw then
-- bw.on_notify_pointer_enter (Current)
-- end
-- end
-- on_pointer_leave
-- -- React to mouse leaving Current
-- do
-- if attached board_world as bw then
-- bw.on_notify_pointer_leave (Current)
-- end
-- end
feature {VITP_WIDGET} -- Implementation
vitp_world: detachable WIDGET_FACTORY
-- The VITP {WIDGET_FACTORY} if any in which Current recursively resides
do
if attached {WIDGET_FACTORY} world as w then
Result := w
elseif attached {WIDGET_FACTORY} group as w then
Result := w
elseif attached {VITP_WIDGET} group as g then
Result := g.vitp_world
end
end
size_values: EV_COORDINATE
-- The difference between the min_values and max_values.
-- The "width" and "height" of the `jj_defining_figure' as a tuple.
local
po: EV_COORDINATE
do
po := points_offset (max_values, min_values)
create Result.make_precise (po.x_precise.abs, po.y_precise.abs)
end
min_values: EV_COORDINATE
-- The smallest values of both the x & y coordinates of all
-- the points in `jj_bounding_figure'
local
i: INTEGER
xx, yy: REAL_64
c: EV_COORDINATE
rect: EV_RECTANGLE
do
-- create c
-- xx := {REAL_64}.Max_value
-- yy := {REAL_64}.Max_value
-- from i := 1
-- until i > jj_bounding_figure.point_count
-- loop
-- c.set_precise (jj_bounding_figure.i_th_point_x (i), jj_bounding_figure.i_th_point_y (i))
-- if c.x_precise < xx then
-- xx := c.x_precise
-- end
-- if c.y_precise < yy then
-- yy := c.y_precise
-- end
-- i := i + 1
-- end
-- create Result.make_precise (xx, yy)
create Result.make_precise (bounding_box.left, bounding_box.top)
end
max_values: EV_COORDINATE
-- The largest values of both the x & y coordinates of all
-- the points in `jj_bounding_figure'
local
i: INTEGER
xx, yy: REAL_64
c: EV_COORDINATE
do
create c
-- xx := {REAL_64}.Min_value
-- yy := {REAL_64}.Min_value
-- from i := 1
-- until i > jj_bounding_figure.point_count
-- loop
-- c.set_precise (jj_bounding_figure.i_th_point_x (i), jj_bounding_figure.i_th_point_y (i))
-- if c.x_precise > xx then
-- xx := c.x_precise
-- end
-- if c.y_precise > yy then
-- yy := c.y_precise
-- end
-- i := i + 1
-- end
-- create Result.make_precise (xx, yy)
create Result.make_precise (bounding_box.right, bounding_box.bottom)
end
points_middle (a_point, a_other_point: EV_COORDINATE): EV_COORDINATE
-- The point midway between the two points
local
xx, yy: REAL_64
do
xx := (a_other_point.x_precise - a_point.x_precise) / 2
yy := (a_other_point.y_precise - a_point.y_precise) / 2
create Result.make_precise (xx, yy)
end
points_offset (a_point, a_other_point: EV_COORDINATE): EV_COORDINATE
-- The offset of `a_other_point' from `a_point'
local
xx, yy: REAL_64
do
xx := a_other_point.x_precise - a_point.x_precise
yy := a_other_point.y_precise - a_point.y_precise
create Result.make_precise (xx, yy)
end
feature {NONE} -- Implementation
degrees_to_radians (degrees: DOUBLE): DOUBLE
-- Convert degrees to radians.
-- Helper function for convienence if need to rotate the widget.
require
degrees_big_enough: degrees >= -360
degrees_small_enough: degrees <= 360
do
Result := degrees * Pi / 180
ensure
-- definition: very_close (Result, degrees * (2 * Pi) / 360)
result_in_range: Result >= -2 * Pi and Result <= 2 * Pi
end
feature {VITP_WIDGET} -- Implementation
name_mt: EV_MODEL_TEXT
-- The name of the object in Current
text_group: EV_MODEL_GROUP
-- Hold any text widgets in Current so they can
-- be positioned and resized as a group
target_imp: detachable VITP_ITEM
-- Detachable implementation of `target' for void safety
invariant
not_empty: target_imp /= Void
end