/tutorial/vision/widget/window_palette2.e

http://github.com/tybor/Liberty · Specman e · 130 lines · 109 code · 13 blank · 8 comment · 5 complexity · fd8f365e7a540798b3d22562a567a902 MD5 · raw file

  1. class WINDOW_PALETTE2
  2. -- Draw color palette on sub_window.
  3. -- Mouse wheel is used to change blue value.
  4. -- Update is done line by line (color line) which avoid the full black window.
  5. -- window and is more responsive to multiple color changes.
  6. inherit
  7. GRAPHIC
  8. creation {ANY}
  9. make
  10. feature {}
  11. sub_window: SUB_WINDOW
  12. make is
  13. local
  14. toplevel_window: TOPLEVEL_WINDOW
  15. do
  16. create toplevel_window.default_create
  17. toplevel_window.when_close_requested(agent vision.loop_stack.break)
  18. toplevel_window.set_background_color(black_color)
  19. toplevel_window.map
  20. toplevel_window.set_shrink(True)
  21. create draw_kit
  22. create sub_window.make(toplevel_window)
  23. sub_window.set_shrink(True)
  24. sub_window.set_expand(True)
  25. sub_window.map
  26. sub_window.when_wheel_up(agent shift(sub_window, 25))
  27. sub_window.when_wheel_down(agent shift(sub_window, -25))
  28. sub_window.when_expose(agent update(sub_window))
  29. progressive_color_refresh := 255
  30. vision.start
  31. end
  32. update (w: WINDOW) is
  33. do
  34. draw_palette(w, blue)
  35. end
  36. progressive_color_refresh: INTEGER
  37. progressive_update (w: WINDOW) is
  38. do
  39. w.clear_area(0,
  40. (progressive_color_refresh * w.height / 256).floor.force_to_integer_32,
  41. w.width,
  42. (w.height / 256).ceiling.force_to_integer_32)
  43. end
  44. blue: INTEGER
  45. shift (w: WINDOW; offset: INTEGER) is
  46. local
  47. blue_value: INTEGER
  48. do
  49. blue_value := blue + offset
  50. if blue_value > 255 then
  51. blue_value := 255
  52. elseif blue_value < 0 then
  53. blue_value := 0
  54. end
  55. if blue_value /= blue then
  56. blue := blue_value
  57. progressive_color_refresh := 0
  58. progressive_update(w)
  59. end
  60. end
  61. draw_kit: DRAW_KIT
  62. draw_palette (w: WINDOW; blue_value: INTEGER) is
  63. require
  64. w /= Void
  65. blue_value.in_range(0, 255)
  66. local
  67. red, green: INTEGER; max_red, max_green: INTEGER; color: COLOR; x, y: INTEGER
  68. width, height: INTEGER; area: RECT
  69. do
  70. draw_kit.set_drawable(w)
  71. area := vision.expose_area.intersect(w.area)
  72. if not area.is_empty then
  73. width := (w.width / 256).ceiling.force_to_integer_32
  74. height := (w.height / 256).ceiling.force_to_integer_32
  75. from
  76. red := scale_from_pos(area.y, w.height, 256)
  77. max_red := scale_from_pos(area.y + area.height - 1, w.height, 256)
  78. max_green := scale_from_pos(area.x + area.width - 1, w.width, 256)
  79. until
  80. red > max_red
  81. loop
  82. y := (w.height * red / 256).floor.force_to_integer_32
  83. from
  84. green := scale_from_pos(area.x, w.width, 256)
  85. until
  86. green > max_green
  87. loop
  88. x := (w.width * green / 256).floor.force_to_integer_32
  89. create color.like_rgb_8(red, green, blue_value)
  90. draw_kit.set_color(color)
  91. draw_kit.fill_rectangle(x, y, width, height)
  92. green := green + 1
  93. end
  94. red := red + 1
  95. end
  96. if progressive_color_refresh < 255 then
  97. progressive_color_refresh := progressive_color_refresh + 1
  98. progressive_update(w)
  99. end
  100. end
  101. end
  102. scale_from_pos (pos, nb_pos, nb_scale: INTEGER): INTEGER is
  103. -- Search nearest inferior scale. Scale position can be
  104. -- computed like this: ((scale*nb_pos)/nb_scale).floor
  105. -- This is equivalent to (scale * nb_pos) // nb_scale
  106. -- scale range from 0 to nb_scale-1
  107. require
  108. pos.in_range(0, nb_pos - 1)
  109. do
  110. Result := (pos * nb_scale / nb_pos).floor.force_to_integer_32
  111. if ((Result + 1) * nb_pos / nb_scale).floor <= pos then
  112. Result := Result + 1
  113. end
  114. ensure
  115. Result.in_range(0, nb_scale - 1)
  116. end
  117. end -- class WINDOW_PALETTE2