/tutorial/vision/widget/window_palette1.e
Specman e | 115 lines | 95 code | 11 blank | 9 comment | 4 complexity | 1aa6d71478e57eeaf69e2075c6137dd6 MD5 | raw file
1class WINDOW_PALETTE1 2 -- Draw color palette on sub_window. 3 -- Mouse wheel is used to change blue value. 4 -- Color rectangle drawing appears on the fly on the screen. 5 -- Drawing is uninterruptible. 6 7inherit 8 GRAPHIC 9 10creation {ANY} 11 make 12 13feature {} 14 sub_window: SUB_WINDOW 15 16 make is 17 local 18 toplevel_window: TOPLEVEL_WINDOW 19 do 20 create toplevel_window.default_create 21 toplevel_window.when_close_requested(agent vision.loop_stack.break) 22 toplevel_window.set_background_color(black_color) 23 toplevel_window.map 24 toplevel_window.set_shrink(True) 25 create draw_kit 26 create sub_window.make(toplevel_window) 27 sub_window.set_shrink(True) 28 sub_window.set_expand(True) 29 sub_window.map 30 sub_window.when_wheel_up(agent shift(sub_window, 25)) 31 sub_window.when_wheel_down(agent shift(sub_window, -25)) 32 sub_window.when_expose(agent update(sub_window)) 33 vision.start 34 end 35 36 update (w: WINDOW) is 37 do 38 draw_palette(w, blue) 39 end 40 41 blue: INTEGER 42 43 shift (w: WINDOW; offset: INTEGER) is 44 local 45 blue_value: INTEGER 46 do 47 blue_value := blue + offset 48 if blue_value > 255 then 49 blue_value := 255 50 elseif blue_value < 0 then 51 blue_value := 0 52 end 53 if blue_value /= blue then 54 blue := blue_value 55 w.refresh 56 end 57 end 58 59 draw_kit: DRAW_KIT 60 61 draw_palette (w: WINDOW; blue_value: INTEGER) is 62 require 63 w /= Void 64 blue_value.in_range(0, 255) 65 local 66 red, green: INTEGER; max_red, max_green: INTEGER; color: COLOR; x, y: INTEGER 67 width, height: INTEGER; area: RECT 68 do 69 draw_kit.set_drawable(w) 70 -- This line is very important here. As w internal characteristic change on each call (while signaling expose), you HAVE TO reassign the window to the draw_kit. 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 -- red increase to the bottom 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 -- green increase to the right 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 end 97 end 98 99 scale_from_pos (pos, nb_pos, nb_scale: INTEGER): INTEGER is 100 -- Search nearest inferior scale. Scale position can be 101 -- computed like this: ((scale*nb_pos)/nb_scale).floor.force_to_integer_32 102 -- This is equivalent to (scale * nb_pos) // nb_scale 103 -- scale range from 0 to nb_scale-1 104 require 105 pos.in_range(0, nb_pos - 1) 106 do 107 Result := (pos * nb_scale / nb_pos).floor.force_to_integer_32 108 if ((Result + 1) * nb_pos / nb_scale).floor.force_to_integer_32 <= pos then 109 Result := Result + 1 110 end 111 ensure 112 Result.in_range(0, nb_scale - 1) 113 end 114 115end -- class WINDOW_PALETTE1