ANY NONE
class interface SUB_WINDOW

creation
   make (p: CONTAINER)

   make_layout (p: CONTAINER; lo: LAYOUT)
      require
         p /= Void;
         lo /= Void;
         lo.container = Void
      ensure
         parent = p;
         layout = lo

   sub_window_create (x, y, w, h: INTEGER; parent_window: WINDOW)
      require
         x.in_range(0,parent_window.width - 1);
         y.in_range(0,parent_window.height - 1);
         w.in_range(1,parent_window.width - x);
         h.in_range(1,parent_window.height - y)

feature(s) from STATE
   state: INTEGER
      -- use values from STATE_CONSTANTS

   is_state_normal: BOOLEAN

   is_state_active: BOOLEAN

   is_state_prelight: BOOLEAN

   is_state_selected: BOOLEAN

   is_state_insensitive: BOOLEAN

feature(s) from STATE
   set_state_normal

   set_state_active

   set_state_prelight

   set_state_selected

   set_state_insensitive

   set_state (n: INTEGER)

   renderer: RENDERER

feature(s) from WIDGET
   parent: CONTAINER

   pos_x: INTEGER

   pos_y: INTEGER

   x_shrink_allowed: BOOLEAN

   x_expand_allowed: BOOLEAN

   y_shrink_allowed: BOOLEAN

   y_expand_allowed: BOOLEAN

   min_width: INTEGER

   min_height: INTEGER

   std_width: INTEGER

   std_height: INTEGER

   width: INTEGER

   height: INTEGER

   valid_width (w: INTEGER): BOOLEAN

   valid_height (h: INTEGER): BOOLEAN

   area: RECT

   root_area: RECT

   computing_size: BOOLEAN
      -- This is only used for invariant defined in widget. Sizes
      -- may be invalid while they are computed

   set_x_shrink (b: BOOLEAN)

   set_x_expand (b: BOOLEAN)

   set_y_shrink (b: BOOLEAN)

   set_y_expand (b: BOOLEAN)

   set_shrink (b: BOOLEAN)
      -- change both x and y shrink state

   set_expand (b: BOOLEAN)
      -- change both x and y expand state

feature(s) from WIDGET
   expose_paint
      -- expose_paint paint with depth limited to the first window
      -- Containers have to propagate, with special
      -- attention to windows where expose_paint do nothing.
      require
         layout /= Void

   set_geometry (x, y, w, h: INTEGER)
      -- Position may be negative (used for scrolling).
      require
         w >= min_width;
         h >= min_height
      require else
         x >= 0;
         y >= 0;
         w >= min_width;
         h >= min_height
      ensure
         width = w;
         height = h

feature(s) from WIDGET
   set_parent (p: CONTAINER)
      require
         p = Void implies parent /= Void;
         p /= Void implies parent = Void;
         p /= Void implies p.has_child(Current)
      ensure
         parent = p

feature(s) from WIDGET
   resize (w, h: INTEGER)
      -- Warning: do not redraw content if not window subtype
      require
         w >= min_width;
         h >= min_height
      ensure
         width = w;
         height = h

feature(s) from DRAWABLE
   clear_without_expose
      -- clear the all the drawable area.
      -- WARNING: don't redraw the content (no expose event)

feature(s) from DRAWABLE
   drawing_widget: POINTER
      -- Because Windows can not paint on widgets like windows or bitmaps,
      -- it needs another object (Device Context) attached to the widget.
      -- For X11, it is the same value as widget.

feature(s) from CONTAINER
   default_create
      -- Default creation method. It is used when no creation
      -- method is specified if allowed. Note it may be renamed.

   make_layout (p: CONTAINER; lo: LAYOUT)
      require
         p /= Void;
         lo /= Void;
         lo.container = Void
      ensure
         parent = p;
         layout = lo

   container_init

feature(s) from CONTAINER
   layout: LAYOUT

   child: FAST_ARRAY[WIDGET]
      -- feature ANY for require validity

   layout_update_paused: BOOLEAN
      --TODO: suppress. Handle this with mapped

   set_layout (l: LAYOUT)
      -- Change the layout for the container (layout choose children
      -- position and size). The layout has to be free (not used
      -- by another container).
      require
         l /= Void;
         l.container = Void
      ensure
         layout = l;
         layout.container = Current;
         not layout_update_paused implies layout_ready

   layout_pause
      --TODO: remove when mapped ready
      require
         not layout_update_paused
      ensure
         layout_update_paused

   layout_continue
      --TODO: remove when mapped ready
      require
         layout_update_paused
      ensure
         layout_ready;
         not layout_update_paused

   child_attach (w: WIDGET)
      -- Add widget w in this container.
      require
         layout /= Void;
         w /= Void;
         w.parent = Void;
         not has_child(w)
      ensure
         w.parent = Current;
         has_child(w);
         last_child = w;
         not layout_update_paused implies layout_ready or not done

   child_detach (w: WIDGET)
      -- Remove widget w from this container.
      require
         w /= Void;
         has_child(w)
      ensure
         child.count = old child.count - 1;
         not has_child(w);
         w.parent = Void;
         not layout_update_paused implies layout_ready

   has_child (w: WIDGET): BOOLEAN

   last_child: WIDGET
      require
         not is_empty

   is_empty: BOOLEAN

   clear_area (x, y, w, h: INTEGER)
      -- clear area and emit expose event (contents will be drawn)
      -- x and y are relative to current object
      require
         w > 0;
         h > 0;
         area.include(x,y);
         area.include(x + w - 1,y + h - 1)

   refresh
      -- clear and update entire object (sub_window(s) are not updated).

   clear
      -- clear and update entire object (sub_window(s) are not updated).

   as_x_root (x: INTEGER): INTEGER
      --TODO: add basic conversion to speed up
      require
         x >= 0;
         x < width
      require else
         x >= pos_x;
         x < pos_x + width

   as_y_root (y: INTEGER): INTEGER
      --TODO: add basic conversion to speed up
      require
         y >= 0;
         y < height
      require else
         y >= pos_y;
         y < pos_y + height

feature(s) from CONTAINER
   done: BOOLEAN
      --TODO: suppress. Handle this with mapped

   child_requisition_changed
      require
         layout /= Void
      ensure
         not layout_update_paused implies layout_ready or not done

feature(s) from CONTAINER
   set_requisition (min_w, min_h, std_w, std_h: INTEGER)
      require
         min_w.in_range(0,std_w);
         min_h.in_range(0,std_h)
      ensure
         not layout_update_paused implies layout_ready or not done

feature(s) from CONTAINER
   layout_ready: BOOLEAN

feature(s) from CONTAINER
   requisition_changed: BOOLEAN

   invalidate_layout
      ensure
         not layout_ready

   update_decoration

   dispatch
      -- Should be called only from set_geometry and set_requisition.
      require
         not layout_ready;
         layout /= Void
      ensure
         layout_ready

   basic_window_clear_area (window: POINTER; x, y, w, h: INTEGER)
      --TODO: invalid for pixmap. Redefine allowed ?

   basic_window_clear_area_no_expose (window: POINTER; x, y, w, h: INTEGER)
      --TODO: invalid for pixmap. Redefine allowed ?

feature(s) from WHEN_LEFT_DOWN
   when_left_down (p: PROCEDURE[ANY,TUPLE])

   when_left_down_signal: SIGNAL_0

feature(s) from WHEN_LEFT_UP
   when_left_up (p: PROCEDURE[ANY,TUPLE])

   when_left_up_signal: SIGNAL_0

feature(s) from WHEN_MIDDLE_DOWN
   when_middle_down (p: PROCEDURE[ANY,TUPLE])

   when_middle_down_signal: SIGNAL_0

feature(s) from WHEN_MIDDLE_UP
   when_middle_up (p: PROCEDURE[ANY,TUPLE])

   when_middle_up_signal: SIGNAL_0

feature(s) from WHEN_RIGHT_DOWN
   when_right_down (p: PROCEDURE[ANY,TUPLE])

   when_right_down_signal: SIGNAL_0

feature(s) from WHEN_RIGHT_UP
   when_right_up (p: PROCEDURE[ANY,TUPLE])

   when_right_up_signal: SIGNAL_0

feature(s) from WHEN_WHEEL_UP
   when_wheel_up (p: PROCEDURE[ANY,TUPLE])

   when_wheel_up_signal: SIGNAL_0

feature(s) from WHEN_WHEEL_DOWN
   when_wheel_down (p: PROCEDURE[ANY,TUPLE])

   when_wheel_down_signal: SIGNAL_0

feature(s) from WHEN_POINTER_MOVE
   when_pointer_move (p: PROCEDURE[ANY,TUPLE[INTEGER, INTEGER]])

   when_pointer_move_signal: SIGNAL_2[INTEGER, INTEGER]

feature(s) from WHEN_POINTER_ENTER
   when_pointer_enter (p: PROCEDURE[ANY,TUPLE])

   when_pointer_enter_signal: SIGNAL_0

feature(s) from WHEN_POINTER_LEAVE
   when_pointer_leave (p: PROCEDURE[ANY,TUPLE])

   when_pointer_leave_signal: SIGNAL_0

feature(s) from WHEN_KEY_DOWN
   when_key_down (p: PROCEDURE[ANY,TUPLE])

   when_key_down_signal: SIGNAL_0

feature(s) from WHEN_MAPPED
   when_mapped (p: PROCEDURE[ANY,TUPLE])

   when_mapped_signal: SIGNAL_0

feature(s) from WHEN_UNMAPPED
   when_unmapped (p: PROCEDURE[ANY,TUPLE])

   when_unmapped_signal: SIGNAL_0

feature(s) from WHEN_GEOMETRY_CHANGE
   when_geometry_change (p: PROCEDURE[ANY,TUPLE[INTEGER, INTEGER, INTEGER, INTEGER]])

   when_geometry_change_signal: SIGNAL_4[INTEGER, INTEGER, INTEGER, INTEGER]

feature(s) from HASHABLE
   hash_code: INTEGER
      -- The hash-code value of Current.
      ensure
         good_hash_value: Result >= 0

feature(s) from SENSITIVE
   widget: POINTER
      -- widget identifier from the native graphic API.

feature(s) from COLOR_LIST
   white_color: COLOR

   black_color: COLOR

   dim_grey_color: COLOR

   dark_grey_color: COLOR

   grey_color: COLOR

   light_grey_color: COLOR

   dark_blue_color: COLOR

   medium_blue_color: COLOR

   blue_color: COLOR

   royal_blue_color: COLOR

   deep_sky_blue_color: COLOR

   sky_blue_color: COLOR

   light_sky_blue_color: COLOR

   steel_blue_color: COLOR

   light_steel_blue_color: COLOR

   light_blue_color: COLOR

   pale_turquoise_color: COLOR

   dark_turquoise_color: COLOR

   medium_turquoise_color: COLOR

   turquoise_color: COLOR

   dark_cyan_color: COLOR

   cyan_color: COLOR

   light_cyan_color: COLOR

   dark_green_color: COLOR

   green_color: COLOR

   light_green_color: COLOR

   yellow_green_color: COLOR

   dark_khaki_color: COLOR

   khaki_color: COLOR

   yellow_color: COLOR

   light_yellow_color: COLOR

   gold_color: COLOR

   beige_color: COLOR

   chocolate_color: COLOR

   firebrick_color: COLOR

   brown_color: COLOR

   dark_salmon_color: COLOR

   salmon_color: COLOR

   light_salmon_color: COLOR

   dark_orange_color: COLOR

   orange_color: COLOR

   orange_red_color: COLOR

   dark_red_color: COLOR

   red_color: COLOR

   hot_pink_color: COLOR

   deep_pink_color: COLOR

   pink_color: COLOR

   light_pink_color: COLOR

   pale_violet_red_color: COLOR

   maroon_color: COLOR

   medium_violet_red_color: COLOR

   violet_red_color: COLOR

   violet_color: COLOR

   dark_magenta_color: COLOR

   magenta_color: COLOR

   dark_violet_color: COLOR

   blue_violet_color: COLOR

   medium_purple_color: COLOR

   purple_color: COLOR

feature(s) from STATE_CONSTANTS
   state_normal: INTEGER

   state_active: INTEGER

   state_prelight: INTEGER

   state_selected: INTEGER

   state_insensitive: INTEGER

feature(s) from ALIGNMENT_CONSTANTS
   center_alignment: ALIGNMENT

   left_alignment: ALIGNMENT

   right_alignment: ALIGNMENT

   top_alignment: ALIGNMENT

   down_alignment: ALIGNMENT

   top_left_alignment: ALIGNMENT

   top_right_alignment: ALIGNMENT

   down_right_alignment: ALIGNMENT

   down_left_alignment: ALIGNMENT

feature(s) from GRAPHIC
   vision: VISION

   font_manager: FONT_MANAGER

   default_font: BASIC_FONT

feature(s) from WHEN_EXPOSE
   when_expose (p: PROCEDURE[ANY,TUPLE])

   when_expose_signal: SIGNAL_0

feature(s) from WINDOW
   default_init

feature(s) from WINDOW
   set_background_color (c: COLOR)
      -- The color is copied, next changes to c won't change the background.
      -- Call clear_area (or refresh) to update the background from
      -- application, not needed from renderer
      require
         c /= Void

   set_background_pixmap (p: PIXMAP)
      -- Call this function again if you modify the pixmap (copy may
      -- have been done)
      require
         p /= Void

   map

   unmap

   mapped: BOOLEAN
      -- Warning: this information is asynchronous

   expose_event

feature(s) from WINDOW
   adjust_size

feature(s) from WINDOW
   paint_decorations (x, y: INTEGER)

   resize_decorations (w, h: INTEGER)

   set_mapped (b: BOOLEAN)

   geometry_changed (x, y, w, h: INTEGER)

   basic_window_create (x, y, w, h: INTEGER; parent_win: POINTER; decorate: BOOLEAN): POINTER

   basic_window_set_geometry (win: POINTER; x, y, w, h: INTEGER)

   basic_window_set_position (win: POINTER; x, y: INTEGER)

   basic_window_set_size (win: POINTER; x, y, w, h: INTEGER)

   basic_window_set_bg_color (win, color: POINTER)

   basic_window_set_bg_pixmap (win, pixmap: POINTER)

   basic_window_clear_no_expose (win: POINTER)

   basic_window_set_kbd_focus (win: POINTER)

   basic_window_map (win: POINTER)

   basic_window_unmap (win: POINTER)

feature(s) from WINDOW
   basic_window_get_drawing_widget (w: POINTER): POINTER

feature(s) from SUB_WINDOW
   make (p: CONTAINER)

   sub_window_create (x, y, w, h: INTEGER; parent_window: WINDOW)
      require
         x.in_range(0,parent_window.width - 1);
         y.in_range(0,parent_window.height - 1);
         w.in_range(1,parent_window.width - x);
         h.in_range(1,parent_window.height - y)


invariant

    width >= 1;

    height >= 1;

    child /= Void;

    width >= min_width or computing_size;

    height >= min_height or computing_size;

    std_width > 0;

    std_height > 0;

    (not x_shrink_allowed implies width >= std_width) or computing_size;

    (not x_expand_allowed implies width <= std_width) or computing_size;

    (not y_shrink_allowed implies height >= std_height) or computing_size;

    (not y_expand_allowed implies height <= std_height) or computing_size;

end of SUB_WINDOW