2020-03-01 09:25:02 +00:00
|
|
|
#include <Array.h>
|
2020-03-19 11:31:59 +00:00
|
|
|
#include <string.h>
|
2020-03-01 09:25:02 +00:00
|
|
|
|
|
|
|
#include "event.h"
|
2020-03-19 11:31:59 +00:00
|
|
|
#include "qwaq-button.h"
|
2020-03-01 09:25:02 +00:00
|
|
|
#include "qwaq-curses.h"
|
2020-03-19 02:32:44 +00:00
|
|
|
#include "qwaq-group.h"
|
2020-03-19 11:31:59 +00:00
|
|
|
#include "qwaq-listener.h"
|
2020-03-23 13:10:03 +00:00
|
|
|
#include "qwaq-titlebar.h"
|
2020-02-29 15:40:55 +00:00
|
|
|
#include "qwaq-window.h"
|
2020-03-01 09:25:02 +00:00
|
|
|
#include "qwaq-view.h"
|
2020-02-29 15:40:55 +00:00
|
|
|
|
|
|
|
@implementation Window
|
2020-03-01 09:25:02 +00:00
|
|
|
|
2020-02-29 15:40:55 +00:00
|
|
|
+windowWithRect: (Rect) rect
|
|
|
|
{
|
|
|
|
return [[[self alloc] initWithRect: rect] autorelease];
|
|
|
|
}
|
2020-03-01 09:25:02 +00:00
|
|
|
|
|
|
|
-initWithRect: (Rect) rect
|
|
|
|
{
|
|
|
|
if (!(self = [super init])) {
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
self.rect = rect;
|
2020-03-19 02:32:44 +00:00
|
|
|
textContext = [[TextContext alloc] initWithRect: rect];
|
|
|
|
panel = create_panel ([(id)textContext window]);
|
|
|
|
|
2020-03-19 07:27:30 +00:00
|
|
|
objects = [[Group alloc] initWithContext: textContext owner: self];
|
|
|
|
|
2020-03-24 04:33:28 +00:00
|
|
|
[self insert: [[TitleBar alloc] initWithTitle:"drag me"]];
|
2020-03-23 13:10:03 +00:00
|
|
|
|
2020-03-23 14:03:35 +00:00
|
|
|
topDrag = [[Button alloc] initWithRect: {{2, 0},
|
|
|
|
{xlen - 4, 1}}];
|
2020-03-23 13:10:03 +00:00
|
|
|
topLeftDrag = [[Button alloc] initWithRect: {{0, 0},
|
2020-03-23 13:27:08 +00:00
|
|
|
{2, 2}}];
|
|
|
|
topRightDrag = [[Button alloc] initWithRect: {{xlen - 2, 0},
|
|
|
|
{2, 2}}];
|
2020-03-23 14:03:35 +00:00
|
|
|
leftDrag = [[Button alloc] initWithRect: {{0, 2},
|
|
|
|
{1, ylen - 4}}];
|
|
|
|
rightDrag = [[Button alloc] initWithRect: {{xlen - 1, 2},
|
|
|
|
{1, ylen - 4}}];
|
2020-03-23 13:27:08 +00:00
|
|
|
bottomLeftDrag = [[Button alloc] initWithRect: {{0, ylen - 2},
|
|
|
|
{2, 2}}];
|
|
|
|
bottomRightDrag = [[Button alloc] initWithRect: {{xlen - 2, ylen - 2},
|
|
|
|
{2, 2}}];
|
2020-03-23 14:03:35 +00:00
|
|
|
bottomDrag = [[Button alloc] initWithRect: {{2, ylen - 1},
|
|
|
|
{xlen - 4, 1}}];
|
2020-03-24 04:33:28 +00:00
|
|
|
[self insert: [topDrag setGrowMode: gfGrowHiX]];
|
|
|
|
[self insert: [topLeftDrag setGrowMode: gfGrowNone]];
|
|
|
|
[self insert: [topRightDrag setGrowMode: gfGrowX]];
|
|
|
|
[self insert: [leftDrag setGrowMode: gfGrowHiY]];
|
|
|
|
[self insert: [rightDrag setGrowMode: gfGrowX | gfGrowHiY]];
|
|
|
|
[self insert: [bottomLeftDrag setGrowMode: gfGrowY]];
|
|
|
|
[self insert: [bottomRightDrag setGrowMode: gfGrowAll]];
|
|
|
|
[self insert: [bottomDrag setGrowMode: gfGrowHiX | gfGrowY]];
|
2020-03-23 13:10:03 +00:00
|
|
|
|
|
|
|
[[topDrag onDrag] addListener: self : @selector(dragWindow:)];
|
|
|
|
[[topLeftDrag onDrag] addListener: self : @selector(dragWindow:)];
|
|
|
|
[[topRightDrag onDrag] addListener: self : @selector(dragWindow:)];
|
|
|
|
[[leftDrag onDrag] addListener: self : @selector(dragWindow:)];
|
|
|
|
[[rightDrag onDrag] addListener: self : @selector(dragWindow:)];
|
|
|
|
[[bottomLeftDrag onDrag] addListener: self : @selector(dragWindow:)];
|
|
|
|
[[bottomRightDrag onDrag] addListener: self : @selector(dragWindow:)];
|
|
|
|
[[bottomDrag onDrag] addListener: self : @selector(dragWindow:)];
|
2020-03-19 11:31:59 +00:00
|
|
|
|
2020-03-13 01:00:05 +00:00
|
|
|
buf = [DrawBuffer buffer: {3, 3}];
|
|
|
|
[buf mvaddstr: {0, 0}, "XOX"];
|
|
|
|
[buf mvaddstr: {0, 1}, "OXO"];
|
|
|
|
[buf mvaddstr: {0, 2}, "XOX"];
|
2020-03-23 11:14:32 +00:00
|
|
|
|
|
|
|
growMode = gfGrowHi;
|
2020-03-24 04:33:28 +00:00
|
|
|
options = ofCanFocus | ofMakeFirst;
|
2020-03-01 09:25:02 +00:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2020-03-23 13:10:03 +00:00
|
|
|
#ifndef max
|
|
|
|
# define max(a,b) ((a) > (b) ? (a) : (b))
|
|
|
|
#endif
|
|
|
|
#ifndef min
|
|
|
|
# define min(a,b) ((a) < (b) ? (a) : (b))
|
|
|
|
#endif
|
|
|
|
#ifndef bound
|
|
|
|
# define bound(a,b,c) (max(a, min(b, c)))
|
|
|
|
#endif
|
|
|
|
|
2020-03-19 11:31:59 +00:00
|
|
|
- (void) dragWindow: (Button *) sender
|
|
|
|
{
|
|
|
|
Point delta = [sender delta];
|
2020-03-23 13:10:03 +00:00
|
|
|
Point dp = nil;
|
|
|
|
Point ds = nil;
|
2020-03-19 12:28:55 +00:00
|
|
|
Extent bounds = [owner size];
|
2020-03-23 13:10:03 +00:00
|
|
|
|
|
|
|
if (sender == topDrag) {
|
|
|
|
dp.x = bound (0, xpos + delta.x, bounds.width - xlen) - xpos;
|
|
|
|
dp.y = bound (0, ypos + delta.y, bounds.height - ylen) - ypos;
|
|
|
|
} else if (sender == topLeftDrag) {
|
|
|
|
dp.x = bound (0, xpos + delta.x, xpos + xlen - 1) - xpos;
|
|
|
|
dp.y = bound (0, ypos + delta.y, ypos + ylen - 1) - ypos;
|
|
|
|
ds.x = bound (1, xlen - delta.x, bounds.width - xpos) - xlen;
|
|
|
|
ds.y = bound (1, ylen - delta.y, bounds.width - ypos) - ylen;
|
|
|
|
} else if (sender == topRightDrag) {
|
|
|
|
dp.y = bound (0, ypos + delta.y, ypos + ylen - 1) - ypos;
|
|
|
|
ds.x = bound (1, xlen + delta.x, bounds.width - xpos) - xlen;
|
|
|
|
ds.y = bound (1, ylen - delta.y, bounds.width - ypos) - ylen;
|
|
|
|
} else if (sender == leftDrag) {
|
|
|
|
dp.x = bound (0, xpos + delta.x, xpos + xlen - 1) - xpos;
|
|
|
|
ds.x = bound (1, xlen - delta.x, bounds.width - xpos) - xlen;
|
|
|
|
} else if (sender == rightDrag) {
|
|
|
|
ds.x = bound (1, xlen + delta.x, bounds.width - xpos) - xlen;
|
|
|
|
} else if (sender == bottomLeftDrag) {
|
|
|
|
dp.x = bound (0, xpos + delta.x, xpos + xlen - 1) - xpos;
|
|
|
|
ds.x = bound (1, xlen - delta.x, bounds.width - xpos) - xlen;
|
|
|
|
ds.y = bound (1, ylen + delta.y, bounds.width - ypos) - ylen;
|
|
|
|
} else if (sender == bottomRightDrag) {
|
|
|
|
ds.x = bound (1, xlen + delta.x, bounds.width - xpos) - xlen;
|
|
|
|
ds.y = bound (1, ylen + delta.y, bounds.width - ypos) - ylen;
|
|
|
|
} else if (sender == bottomDrag) {
|
|
|
|
ds.y = bound (1, ylen + delta.y, bounds.width - ypos) - ylen;
|
2020-03-19 12:28:55 +00:00
|
|
|
}
|
2020-03-23 13:10:03 +00:00
|
|
|
int save_state = state;
|
|
|
|
state &= ~sfDrawn;
|
|
|
|
[self move: dp];
|
|
|
|
[self resize: {ds.x, ds.y}];
|
|
|
|
state = save_state;
|
|
|
|
[self redraw];
|
2020-03-19 11:31:59 +00:00
|
|
|
}
|
|
|
|
|
2020-03-19 02:32:44 +00:00
|
|
|
-setContext: (id<TextContext>) context
|
|
|
|
{
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2020-03-23 13:10:03 +00:00
|
|
|
-move: (Point) delta
|
|
|
|
{
|
|
|
|
int save_state = state;
|
|
|
|
state &= ~sfDrawn;
|
|
|
|
[super move: delta];
|
|
|
|
move_panel (panel, xpos, ypos);
|
|
|
|
state = save_state;
|
|
|
|
[self redraw];
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2020-03-23 11:14:32 +00:00
|
|
|
-resize: (Extent) delta
|
|
|
|
{
|
|
|
|
Extent size = self.size;
|
|
|
|
[super resize:delta];
|
|
|
|
delta = {self.size.width - size.width, self.size.height - size.height};
|
|
|
|
[(id)textContext resizeTo: self.size];
|
|
|
|
replace_panel (panel, [(id)textContext window]);
|
|
|
|
[objects resize:delta];
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2020-03-01 09:25:02 +00:00
|
|
|
-handleEvent: (qwaq_event_t *) event
|
|
|
|
{
|
2020-03-24 04:46:26 +00:00
|
|
|
int offset = event.what & qe_positional;
|
|
|
|
|
|
|
|
if (offset) {
|
|
|
|
event.mouse.x -= xpos;
|
|
|
|
event.mouse.y -= ypos;
|
|
|
|
}
|
2020-03-19 07:27:30 +00:00
|
|
|
[objects handleEvent: event];
|
2020-03-24 04:46:26 +00:00
|
|
|
if (offset) {
|
|
|
|
event.mouse.x += xpos;
|
|
|
|
event.mouse.y += ypos;
|
|
|
|
}
|
2020-03-01 09:25:02 +00:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2020-03-24 04:33:28 +00:00
|
|
|
-takeFocus
|
|
|
|
{
|
|
|
|
[super takeFocus];
|
|
|
|
[objects takeFocus];
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
-loseFocus
|
|
|
|
{
|
|
|
|
[super loseFocus];
|
|
|
|
[objects loseFocus];
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
-insert: (View *) view
|
2020-03-01 09:25:02 +00:00
|
|
|
{
|
2020-03-19 07:27:30 +00:00
|
|
|
[objects insert: view];
|
2020-03-01 09:25:02 +00:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2020-03-24 04:33:28 +00:00
|
|
|
-insertDrawn: (View *) view
|
|
|
|
{
|
|
|
|
[objects insertDrawn: view];
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
-insertSelected: (View *) view
|
|
|
|
{
|
|
|
|
[objects insertSelected: view];
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2020-03-01 09:25:02 +00:00
|
|
|
-setBackground: (int) ch
|
|
|
|
{
|
2020-03-19 02:32:44 +00:00
|
|
|
[(id)textContext bkgd: ch];
|
2020-03-01 09:25:02 +00:00
|
|
|
return self;
|
|
|
|
}
|
2020-03-02 06:22:54 +00:00
|
|
|
|
|
|
|
-draw
|
|
|
|
{
|
2020-03-05 15:32:09 +00:00
|
|
|
static box_sides_t box_sides = {
|
|
|
|
ACS_VLINE, ACS_VLINE,
|
|
|
|
ACS_HLINE, ACS_HLINE,
|
|
|
|
};
|
|
|
|
static box_corners_t box_corners = {
|
|
|
|
ACS_ULCORNER, ACS_URCORNER,
|
|
|
|
ACS_LLCORNER, ACS_LRCORNER,
|
|
|
|
};
|
|
|
|
if (box_sides.ls == ACS_VLINE) {
|
|
|
|
int *foo = &box_sides.ls;
|
|
|
|
for (int i = 0; i < 8; i++) {
|
|
|
|
foo[i] = acs_char (foo[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
[super draw];
|
2020-03-19 02:32:44 +00:00
|
|
|
[(id)textContext border: box_sides, box_corners];
|
2020-03-19 07:27:30 +00:00
|
|
|
[objects draw];
|
2020-03-03 12:30:47 +00:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
-redraw
|
|
|
|
{
|
2020-03-23 13:10:03 +00:00
|
|
|
if (state & sfDrawn) {
|
|
|
|
[owner redraw];
|
|
|
|
}
|
|
|
|
return self;
|
2020-03-03 12:30:47 +00:00
|
|
|
}
|
2020-03-06 08:46:36 +00:00
|
|
|
|
|
|
|
- (void) mvprintf: (Point) pos, string fmt, ...
|
|
|
|
{
|
|
|
|
[textContext mvvprintf: pos, fmt, @args];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) mvvprintf: (Point) pos, string fmt, @va_list args
|
|
|
|
{
|
|
|
|
[textContext mvvprintf: pos, fmt, args];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) mvaddch: (Point) pos, int ch
|
|
|
|
{
|
|
|
|
[textContext mvaddch: pos, ch];
|
|
|
|
}
|
2020-02-29 15:40:55 +00:00
|
|
|
@end
|