# # $Id: sizer.icn,v 1.6 2004/11/13 23:40:17 rparlett Exp $ # # This file is in the public domain. # # Author: Robert Parlett (parlett@dial.pipex.com) # package gui link graphics $include "guih.icn" # # This class provides a component which can be dragged across the # window, allowing panes within the window to be resized. A SIZER_RELEASED_EVENT is # generated when the {Sizer} has been dragged and released. The new position # may then be obtained and the dialog adjusted accordingly. # # class Sizer : Component( is_held, is_horizontal_flag, # temp_win, # temp_w, temp_h, lo, hi, drag_offset, curr_pos, start_pos, end_pos, pointer_flag ) # # Set the minimum and maximum values for the {Sizer}. Whether these are # x or y values depends on the orientation of the {Sizer}. # method set_range(lo, hi) self.lo := lo self.hi := hi end # # Return the current position of the {Sizer}. This may be invoked to determine # where the {Sizer} has been dragged to after it has generated an event. # method get_curr_pos() return curr_pos end # # Get the size of the move during the last drag of the {Sizer}. # method get_delta() return end_pos - start_pos end # # Configure the {Sizer} to be horizontal; the default is vertical. # method set_is_horizontal() return self.is_horizontal_flag := 1 end # # Configure the {Sizer} to be vertical; the default. # method clear_is_horizontal() return self.is_horizontal_flag := &null end method finally() if \self.is_held then { WClose(self.temp_win) unique_end() } self.Component.finally() end method display(buffer_flag) local cw if \self.is_held then { CopyArea(temp_win, cbwin, 0, 0, temp_w, temp_h, 0, 0) cw := Clone(self.cbwin, "linewidth=4", "pattern=gray", "fillstyle=masked") if \is_horizontal_flag then { abs_pos := curr_pos + drag_offset + parent.get_y_reference() DrawLine(cw, x, abs_pos, x + w, abs_pos) } else { abs_pos := curr_pos + drag_offset + parent.get_x_reference() DrawLine(cw, abs_pos, y, abs_pos, y + h) } Uncouple(cw) CopyArea(get_parent_buffer_win(), get_parent_win(), 0, 0, temp_w, temp_h, 0, 0) } else { EraseRectangle(self.cbwin, self.x, self.y, self.w, self.h) DrawRaisedRectangle(self.cbwin, self.x, self.y, self.w, self.h, 1) self.do_shading(self.cbwin) if /buffer_flag then CopyArea(self.cbwin, self.cwin, self.x, self.y, self.w, self.h, self.x, self.y) } end method set_curr_pos() if \self.is_horizontal_flag then curr_pos := &y - drag_offset - parent.get_y_reference() else curr_pos := &x - drag_offset - parent.get_x_reference() curr_pos <:= \lo curr_pos >:= \hi return curr_pos end # # Change the pointer to be the double arrow (unless it is already). # @p method pointer_on() if /pointer_flag then { if \self.is_horizontal_flag then get_parent_dialog().change_pointer("sb v double arrow") else get_parent_dialog().change_pointer("sb h double arrow") pointer_flag := 1 } end method resize() if /self.is_horizontal_flag then /self.w_spec := 6 else /self.h_spec := 6 self.Component.resize() end # # Reset the pointer if needed. # method pointer_off() if \pointer_flag then { get_parent_dialog().restore_pointer() pointer_flag := &null } end method handle_event(e) if e === -12 then { if self.in_region() then pointer_on() else pointer_off() } else if e === (&lpress | &rpress | &mpress) then { if self.in_region() then { unique_start() self.is_held := 1 temp_w := parent_dialog.get_w_reference() temp_h := parent_dialog.get_h_reference() self.temp_win := WOpen("canvas=hidden", "size=" || temp_w || "," || temp_h) CopyArea(cwin, temp_win, 0, 0, temp_w, temp_h, 0, 0) if \self.is_horizontal_flag then { drag_offset := &y - self.y } else { drag_offset := &x - self.x } pointer_on() start_pos := set_curr_pos() self.invalidate() } } else if \self.is_held then { if e === (&ldrag | &rdrag | &mdrag) then { set_curr_pos() self.invalidate() } else if e === (&lrelease | &rrelease | &mrelease) then { self.is_held := &null pointer_off() end_pos := set_curr_pos() CopyArea(temp_win, cwin, 0, 0, temp_w, temp_h, 0, 0) WClose(self.temp_win) unique_end() fire(SIZER_RELEASED_EVENT, e) } } end method set_one(attr, val) case attr of { "is_horizontal" : if test_flag(attr, val) then set_is_horizontal() else clear_is_horizontal() "range" : set_range!int_vals(attr, val) default: self.Component.set_one(attr, val) } end initially(a[]) self.Component.initially() set_fields(a) end