--OSWindow-- __index = OSEntity type = "OSWindow" title = "" entities = {} environment = nil dragX = 0 --for getting the relative postion of the window when dragging canMaximise = true canMinimise = true isMinimised = false canClose = true hasFrame = true BackgroundColour = colours.white FrameTextColour = colours.black FocusFrameColour = colours.lightGrey ButtonTextColour = colours.white CloseColour = colours.red MinimiseColour = colours.orange MaximiseColour = colours.lime HandleCharacter = "%" HandleColour = colours.lightGrey HandleBackgroundColour = colours.white minWidth = 10 minHeight = 5 minimiseDockItem = nil close = function(self) --first check whether the application is ok with the close (or the checking function is not set) if self.canClose then if self.environment.windowShouldClose == nil or self.environment.windowShouldClose(self) then term.setTextColour(colours.white) --remove the window from the window list local i = 0 for _,window in pairs(self.environment.windows) do i = i + 1 if window == self then --remove the entity self.environment.windows[_]=nil OSServices.compactArray(self.environment.windows) if self.environment.windowDidClose then self.environment.windowDidClose(self) end OSUpdate() break end end end end end minimise = function(self) if not self.isMinimised then self.isMinimised = true OSCurrentWindow = nil OSSelectedEntity = nil self.minimiseDockItem = OSDockItem:newMinimise(self) OSDock:add(self.minimiseDockItem) OSUpdate() end end restore = function(self) if self.isMinimised then OSDock:remove(self.minimiseDockItem) self.minimiseItem = nil self.isMinimised = false OSCurrentWindow = self OSUpdate() end end maximise = function(self) self.x = 1 self.y = 2 self:resize(OSServices.availableScreenSize()) end resize = function(self, w, h) if not self.canMaximise then return end if w <= self.minWidth then w = self.minWidth end if h <= self.minHeight then h = self.minHeight end self.width = w self.height = h if self.environment.windowDidResize then self.environment.windowDidResize(self, w, h - 1) end OSUpdate() end action = function(self, x, y) --if the y of the click was 0 (the window frame) do special actions if y == 0 then if x == 1 then --close button self:close() elseif x == 2 and self.canMinimise then --minimise button self:minimise() elseif x == 3 and self.canMaximise then --maximise button self:maximise() else --main bar self.dragX = x - 1 OSWindowDragTimer = os.startTimer(OSServices.dragTimeout) end elseif x == self.width and y == self.height - 1 then OSWindowResizeTimer = os.startTimer(OSServices.dragTimeout) else -- it was in the window content for _,entity in pairs(self.entities) do --check if the click overlaps an entities if OSServices.pointOverlapsRect({x = x, y = y}, entity) then if OSServices.clickEntity(entity, x, y) then OSUpdate() return end end end end OSUpdate() end Draw = function(self) if self.isMinimised then return end OSDrawing.setOffset(self.x, self.y + 1) -- 1 is added to the y offset because of the title bar if self.hasFrame then --draw the title bar local frameColour = OSWindow.FocusFrameColour if not self == OSCurrentWindow then frameColour = OSWindow.FrameColour end OSDrawing.DrawBlankArea(1, 0, self.width, 1, frameColour) --draw the title bar buttons if self.canClose then OSDrawing.DrawCharacters(1, 0, "x", OSWindow.ButtonTextColour, OSWindow.CloseColour) end if self.canMinimise then OSDrawing.DrawCharacters(2, 0, "-", OSWindow.ButtonTextColour, OSWindow.MinimiseColour) end if self.canMaximise then OSDrawing.DrawCharacters(3, 0, "+", OSWindow.ButtonTextColour, OSWindow.MaximiseColour) end --draw the title local titleX = math.max(math.ceil((self.width / 2) - (#self.title / 2)), 0) OSDrawing.DrawCharacters(titleX, 0, self.title, OSWindow.FrameTextColour, OSWindow.FocusFrameColour) end --draw the window background OSDrawing.DrawBlankArea(1, 1, self.width, self.height - 1, OSWindow.BackgroundColour) --draw the shadow OSDrawing.DrawShadow(1, 0, self.width, self.height) --draw the controls for _,entity in pairs(self.entities) do entity:Draw() end if self.canMaximise then --draw the drag handle OSDrawing.DrawCharacters(self.width, self.height-1, self.HandleCharacter, OSWindow.HandleColour, OSWindow.HandleBackgroundColour) end end new = function(self, _title, _entities, _width, _height, _environment) local new = {} -- the new instance setmetatable( new, {__index = OSWindow} ) new.title = _title new.entities = _entities new.width = _width new.height = _height + 1 --for the menu bar local w, h = OSServices.availableScreenSize() new.x = math.ceil((w - _width) / 2) new.y = math.ceil((h - _height) / 2) + 1 new.id = OSServices.generateID() new.environment = _environment OSCurrentWindow = new return new end