ANY NONE
class interface DECORATOR
   -- The most complex decorator

creation
   make (s: BOOLEAN)
      ensure
         scaleable = s

feature(s) from STATE_CONSTANTS
   state_normal: INTEGER

   state_active: INTEGER

   state_prelight: INTEGER

   state_selected: INTEGER

   state_insensitive: INTEGER

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

   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.

   set_geometry (x, y, w, h: INTEGER)
      require
         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)
      require
         w >= min_width;
         h >= min_height
      ensure
         width = w;
         height = h

feature(s) from DECORATION
   set_widget (w: POINTER)

   widget: POINTER

   max_width: INTEGER

   max_height: INTEGER

feature(s) from DECORATOR
   make (s: BOOLEAN)
      ensure
         scaleable = s

   scaleable: BOOLEAN
      -- if True, the points are modified when the decorator is resized

feature(s) from DECORATOR
   add_segment (x1, y1, x2, y2: INTEGER)

   add_arc (x, y, w, h, angle1, angle2: INTEGER)

   add_polygon (x1, y1, x2, y2: INTEGER)

   add_pie (x, y, w, h, angle1, angle2: INTEGER)

   paint (x, y: INTEGER)

feature(s) from DECORATOR
   -- Adding segments or polygons:
   -- In those algorithms we call "segment" any array of one or more points:
   -- indeed, of type FAST_ARRAY[POINT]

   show (dictionary: HASHED_DICTIONARY[FAST_ARRAY[FAST_ARRAY[POINT]], POINT])

   do_add_segment (x1, y1, x2, y2: INTEGER; dictionary: HASHED_DICTIONARY[FAST_ARRAY[FAST_ARRAY[POINT]], POINT]; list: FAST_ARRAY[FAST_ARRAY[POINT]])

   exists_segment (p1, p2: POINT; dictionary: HASHED_DICTIONARY[FAST_ARRAY[FAST_ARRAY[POINT]], POINT]): BOOLEAN
      require
         dictionary.has(p1);
         dictionary.has(p2)

   try_add_point_to_segment (p: POINT; segs: FAST_ARRAY[FAST_ARRAY[POINT]]; anchor: POINT; dictionary: HASHED_DICTIONARY[FAST_ARRAY[FAST_ARRAY[POINT]], POINT]; list: FAST_ARRAY[FAST_ARRAY[POINT]])
      require
         --segs.exists(agent {FAST_ARRAY[POINT]}.has(anchor))
         dictionary.has(anchor)

   make_segment_in (p1, p2: POINT; segs, list: FAST_ARRAY[FAST_ARRAY[POINT]])

   make_segment (p1, p2: POINT; dictionary: HASHED_DICTIONARY[FAST_ARRAY[FAST_ARRAY[POINT]], POINT]; list: FAST_ARRAY[FAST_ARRAY[POINT]])

   join (seg1, seg2: FAST_ARRAY[POINT]; first, backwards: BOOLEAN)
      -- Add seg2 to seg1.
      -- If first, prepend it; otherwise append it.
      -- If backwards, add it in reverse order.

feature(s) from DECORATOR
   -- Adding arcs and pies:

   do_add_arc (x, y, w, h, angle1, angle2: INTEGER; dictionary: HASHED_DICTIONARY[HASHED_DICTIONARY[FAST_ARRAY[ARC], POINT], POINT]; list: FAST_ARRAY[ARC])

feature(s) from DECORATOR
   -- Painting:

   last_x: INTEGER

   last_y: INTEGER

   do_paint_segments (x, y: INTEGER; fill: BOOLEAN; list: FAST_ARRAY[FAST_ARRAY[POINT]])

   do_paint_arcs (x, y: INTEGER; fill: BOOLEAN; list: FAST_ARRAY[ARC])

feature(s) from DECORATOR
   -- Resizing:

   do_resize (w, h: INTEGER)

   do_scale_segments (scale_w, scale_h: DOUBLE)

   do_scale_arcs (scale_w, scale_h: DOUBLE)

   do_scale_polygons (scale_w, scale_h: DOUBLE)

   do_scale_pies (scale_w, scale_h: DOUBLE)

feature(s) from DECORATOR
   -- Structure:
   -- The structure is pretty complex.
   -- SEGMENTS:
   --  - The dictionary has points as keys. Each point links to every segment
   --    having it (as an end or not!)
   --  - The list allows fast painting of all segments
   --  - Polygons are filled segments
   -- ARCS:
   --  - The dictionary has centers as keys. Each point links to another
   --    dictionary; this one has (width, height) as keys. Those keys in turn
   --    point to every arc having this center and this size.
   --  - The list allows fast painting of all arcs
   --  - Pies are filled arcs

   dic_arcs: HASHED_DICTIONARY[HASHED_DICTIONARY[FAST_ARRAY[ARC], POINT], POINT]

   dic_segments: HASHED_DICTIONARY[FAST_ARRAY[FAST_ARRAY[POINT]], POINT]

   dic_pies: HASHED_DICTIONARY[HASHED_DICTIONARY[FAST_ARRAY[ARC], POINT], POINT]

   dic_polygons: HASHED_DICTIONARY[FAST_ARRAY[FAST_ARRAY[POINT]], POINT]

   all_arcs: FAST_ARRAY[ARC]

   all_segments: FAST_ARRAY[FAST_ARRAY[POINT]]

   all_pies: FAST_ARRAY[ARC]

   all_polygons: FAST_ARRAY[FAST_ARRAY[POINT]]

feature(s) from DECORATOR
   -- Basics:

   basic_guikit_drawlines (peer: POINTER; points: POINTER; count_points: INTEGER; dx, dy: INTEGER)

   basic_guikit_fillpolygon (peer: POINTER; points: POINTER; count_points: INTEGER; dx, dy: INTEGER)

   basic_guikit_drawarcs (peer: POINTER; arcs: POINTER; count_arcs: INTEGER; dx, dy: INTEGER)

   basic_guikit_fillarcs (peer: POINTER; arcs: POINTER; count_arcs: INTEGER; dx, dy: INTEGER)

   basic_guikit_point_size: INTEGER

   basic_guikit_arc_size: INTEGER


invariant

    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 DECORATOR