144 { |
144 { |
145 Window *w; |
145 Window *w; |
146 DrawPixelInfo bk; |
146 DrawPixelInfo bk; |
147 _cur_dpi = &bk; |
147 _cur_dpi = &bk; |
148 |
148 |
149 for(w=_windows; w!=_last_window; w++) { |
149 for (w = _windows; w != _last_window; w++) { |
150 if (right > w->left && |
150 if (right > w->left && |
151 bottom > w->top && |
151 bottom > w->top && |
152 left < w->left + w->width && |
152 left < w->left + w->width && |
153 top < w->top + w->height) { |
153 top < w->top + w->height) { |
154 DrawOverlappedWindow(w, left, top, right, bottom); |
154 DrawOverlappedWindow(w, left, top, right, bottom); |
155 } |
155 } |
156 } |
156 } |
157 } |
157 } |
158 |
158 |
159 void DrawOverlappedWindow(Window *w, int left, int top, int right, int bottom) |
159 void DrawOverlappedWindow(Window *w, int left, int top, int right, int bottom) |
160 { |
160 { |
164 while (++v != _last_window) { |
164 while (++v != _last_window) { |
165 if (right > v->left && |
165 if (right > v->left && |
166 bottom > v->top && |
166 bottom > v->top && |
167 left < v->left + v->width && |
167 left < v->left + v->width && |
168 top < v->top + v->height) { |
168 top < v->top + v->height) { |
169 |
|
170 if (left < (x=v->left)) { |
169 if (left < (x=v->left)) { |
171 DrawOverlappedWindow(w, left, top, x, bottom); |
170 DrawOverlappedWindow(w, left, top, x, bottom); |
172 DrawOverlappedWindow(w, x, top, right, bottom); |
171 DrawOverlappedWindow(w, x, top, right, bottom); |
173 return; |
172 return; |
174 } |
173 } |
349 * @return w pointer to the window that is going to be deleted |
344 * @return w pointer to the window that is going to be deleted |
350 */ |
345 */ |
351 static Window *FindDeletableWindow(void) |
346 static Window *FindDeletableWindow(void) |
352 { |
347 { |
353 Window *w; |
348 Window *w; |
|
349 |
354 for (w = _windows; w < endof(_windows); w++) { |
350 for (w = _windows; w < endof(_windows); w++) { |
355 if (w->window_class != WC_MAIN_WINDOW && !IsVitalWindow(w) && !(w->flags4 & WF_STICKY) ) |
351 if (w->window_class != WC_MAIN_WINDOW && !IsVitalWindow(w) && !(w->flags4 & WF_STICKY)) { |
356 return w; |
352 return w; |
|
353 } |
357 } |
354 } |
358 return NULL; |
355 return NULL; |
359 } |
356 } |
360 |
357 |
361 /** A window must be freed, and all are marked as important windows. Ease the |
358 /** A window must be freed, and all are marked as important windows. Ease the |
365 * @return w Pointer to the window that is being deleted |
362 * @return w Pointer to the window that is being deleted |
366 */ |
363 */ |
367 static Window *ForceFindDeletableWindow(void) |
364 static Window *ForceFindDeletableWindow(void) |
368 { |
365 { |
369 Window *w; |
366 Window *w; |
|
367 |
370 for (w = _windows;; w++) { |
368 for (w = _windows;; w++) { |
371 assert(w < _last_window); |
369 assert(w < _last_window); |
372 |
370 if (w->window_class != WC_MAIN_WINDOW && !IsVitalWindow(w)) return w; |
373 if (w->window_class != WC_MAIN_WINDOW && !IsVitalWindow(w)) |
|
374 return w; |
|
375 } |
371 } |
376 } |
372 } |
377 |
373 |
378 bool IsWindowOfPrototype(const Window* w, const Widget* widget) |
374 bool IsWindowOfPrototype(const Window* w, const Widget* widget) |
379 { |
375 { |
384 void AssignWidgetToWindow(Window *w, const Widget *widget) |
380 void AssignWidgetToWindow(Window *w, const Widget *widget) |
385 { |
381 { |
386 w->original_widget = widget; |
382 w->original_widget = widget; |
387 |
383 |
388 if (widget != NULL) { |
384 if (widget != NULL) { |
389 const Widget *wi = widget; |
|
390 uint index = 1; |
385 uint index = 1; |
391 while (wi->type != WWT_LAST) { |
386 const Widget* wi; |
392 wi++; |
387 |
393 index++; |
388 for (wi = widget; wi->type != WWT_LAST; wi++) index++; |
394 } |
389 |
395 |
390 w->widget = realloc(w->widget, sizeof(*w->widget) * index); |
396 w->widget = realloc(w->widget, sizeof(Widget) * index); |
391 memcpy(w->widget, widget, sizeof(*w->widget) * index); |
397 memcpy(w->widget, widget, sizeof(Widget) * index); |
392 } else { |
398 } else |
|
399 w->widget = NULL; |
393 w->widget = NULL; |
|
394 } |
400 } |
395 } |
401 |
396 |
402 /** Open a new window. If there is no space for a new window, close an open |
397 /** Open a new window. If there is no space for a new window, close an open |
403 * window. Try to avoid stickied windows, but if there is no else, close one of |
398 * window. Try to avoid stickied windows, but if there is no else, close one of |
404 * those as well. Then make sure all created windows are below some always-on-top |
399 * those as well. Then make sure all created windows are below some always-on-top |
420 |
415 |
421 // We have run out of windows, close one and use that as the place for our new one |
416 // We have run out of windows, close one and use that as the place for our new one |
422 if (w >= endof(_windows)) { |
417 if (w >= endof(_windows)) { |
423 w = FindDeletableWindow(); |
418 w = FindDeletableWindow(); |
424 |
419 |
425 if (w == NULL) // no window found, force it! |
420 if (w == NULL) w = ForceFindDeletableWindow(); |
426 w = ForceFindDeletableWindow(); |
|
427 |
421 |
428 DeleteWindow(w); |
422 DeleteWindow(w); |
429 w = _last_window; |
423 w = _last_window; |
430 } |
424 } |
431 |
425 |
501 if (w == NULL || w->left >= (_screen.width-20) || w->left <= -60 || w->top >= (_screen.height-20)) { |
495 if (w == NULL || w->left >= (_screen.width-20) || w->left <= -60 || w->top >= (_screen.height-20)) { |
502 return AllocateWindowAutoPlace(width,height,proc,cls,widget); |
496 return AllocateWindowAutoPlace(width,height,proc,cls,widget); |
503 } |
497 } |
504 |
498 |
505 x = w->left; |
499 x = w->left; |
506 if (x > _screen.width - width) |
500 if (x > _screen.width - width) x = _screen.width - width - 20; |
507 x = (_screen.width - width) - 20; |
501 |
508 |
502 return AllocateWindow(x + 10, w->top + 10, width, height, proc, cls, widget); |
509 return AllocateWindow(x+10,w->top+10,width,height,proc,cls,widget); |
|
510 } |
503 } |
511 |
504 |
512 |
505 |
513 typedef struct SizeRect { |
506 typedef struct SizeRect { |
514 int left,top,width,height; |
507 int left,top,width,height; |
529 |
522 |
530 if (left < 0 || top < 22 || right > _screen.width || bottom > _screen.height) |
523 if (left < 0 || top < 22 || right > _screen.width || bottom > _screen.height) |
531 return false; |
524 return false; |
532 |
525 |
533 // Make sure it is not obscured by any window. |
526 // Make sure it is not obscured by any window. |
534 for(w=_windows; w!=_last_window; w++) { |
527 for (w = _windows; w != _last_window; w++) { |
535 if (w->window_class == WC_MAIN_WINDOW) |
528 if (w->window_class == WC_MAIN_WINDOW) continue; |
536 continue; |
|
537 |
529 |
538 if (right > w->left && |
530 if (right > w->left && |
539 w->left + w->width > left && |
531 w->left + w->width > left && |
540 bottom > w->top && |
532 bottom > w->top && |
541 w->top + w->height > top) |
533 w->top + w->height > top) { |
542 return false; |
534 return false; |
|
535 } |
543 } |
536 } |
544 |
537 |
545 return true; |
538 return true; |
546 } |
539 } |
547 |
540 |
559 return false; |
552 return false; |
560 if (top < 22 || top > _screen.height - (height>>2)) |
553 if (top < 22 || top > _screen.height - (height>>2)) |
561 return false; |
554 return false; |
562 |
555 |
563 // Make sure it is not obscured by any window. |
556 // Make sure it is not obscured by any window. |
564 for(w=_windows; w!=_last_window; w++) { |
557 for (w = _windows; w != _last_window; w++) { |
565 if (w->window_class == WC_MAIN_WINDOW) |
558 if (w->window_class == WC_MAIN_WINDOW) continue; |
566 continue; |
|
567 |
559 |
568 if (left + width > w->left && |
560 if (left + width > w->left && |
569 w->left + w->width > left && |
561 w->left + w->width > left && |
570 top + height > w->top && |
562 top + height > w->top && |
571 w->top + w->height > top) |
563 w->top + w->height > top) { |
572 return false; |
564 return false; |
|
565 } |
573 } |
566 } |
574 |
567 |
575 return true; |
568 return true; |
576 } |
569 } |
577 |
570 |
583 _awap_r.width = width; |
576 _awap_r.width = width; |
584 _awap_r.height = height; |
577 _awap_r.height = height; |
585 |
578 |
586 if (IsGoodAutoPlace1(0, 24)) goto ok_pos; |
579 if (IsGoodAutoPlace1(0, 24)) goto ok_pos; |
587 |
580 |
588 for(w=_windows; w!=_last_window; w++) { |
581 for (w = _windows; w != _last_window; w++) { |
589 if (w->window_class == WC_MAIN_WINDOW) |
582 if (w->window_class == WC_MAIN_WINDOW) continue; |
590 continue; |
|
591 |
583 |
592 if (IsGoodAutoPlace1(w->left+w->width+2,w->top)) goto ok_pos; |
584 if (IsGoodAutoPlace1(w->left+w->width+2,w->top)) goto ok_pos; |
593 if (IsGoodAutoPlace1(w->left- width-2,w->top)) goto ok_pos; |
585 if (IsGoodAutoPlace1(w->left- width-2,w->top)) goto ok_pos; |
594 if (IsGoodAutoPlace1(w->left,w->top+w->height+2)) goto ok_pos; |
586 if (IsGoodAutoPlace1(w->left,w->top+w->height+2)) goto ok_pos; |
595 if (IsGoodAutoPlace1(w->left,w->top- height-2)) goto ok_pos; |
587 if (IsGoodAutoPlace1(w->left,w->top- height-2)) goto ok_pos; |
597 if (IsGoodAutoPlace1(w->left- width-2,w->top+w->height-height)) goto ok_pos; |
589 if (IsGoodAutoPlace1(w->left- width-2,w->top+w->height-height)) goto ok_pos; |
598 if (IsGoodAutoPlace1(w->left+w->width-width,w->top+w->height+2)) goto ok_pos; |
590 if (IsGoodAutoPlace1(w->left+w->width-width,w->top+w->height+2)) goto ok_pos; |
599 if (IsGoodAutoPlace1(w->left+w->width-width,w->top- height-2)) goto ok_pos; |
591 if (IsGoodAutoPlace1(w->left+w->width-width,w->top- height-2)) goto ok_pos; |
600 } |
592 } |
601 |
593 |
602 for(w=_windows; w!=_last_window; w++) { |
594 for (w = _windows; w != _last_window; w++) { |
603 if (w->window_class == WC_MAIN_WINDOW) |
595 if (w->window_class == WC_MAIN_WINDOW) continue; |
604 continue; |
|
605 |
596 |
606 if (IsGoodAutoPlace2(w->left+w->width+2,w->top)) goto ok_pos; |
597 if (IsGoodAutoPlace2(w->left+w->width+2,w->top)) goto ok_pos; |
607 if (IsGoodAutoPlace2(w->left- width-2,w->top)) goto ok_pos; |
598 if (IsGoodAutoPlace2(w->left- width-2,w->top)) goto ok_pos; |
608 if (IsGoodAutoPlace2(w->left,w->top+w->height+2)) goto ok_pos; |
599 if (IsGoodAutoPlace2(w->left,w->top+w->height+2)) goto ok_pos; |
609 if (IsGoodAutoPlace2(w->left,w->top- height-2)) goto ok_pos; |
600 if (IsGoodAutoPlace2(w->left,w->top- height-2)) goto ok_pos; |
645 |
636 |
646 Window *AllocateWindowDescFront(const WindowDesc *desc, int value) |
637 Window *AllocateWindowDescFront(const WindowDesc *desc, int value) |
647 { |
638 { |
648 Window *w; |
639 Window *w; |
649 |
640 |
650 if (BringWindowToFrontById(desc->cls, value)) |
641 if (BringWindowToFrontById(desc->cls, value)) return NULL; |
651 return NULL; |
|
652 w = AllocateWindowDesc(desc); |
642 w = AllocateWindowDesc(desc); |
653 w->window_number = value; |
643 w->window_number = value; |
654 return w; |
644 return w; |
655 } |
645 } |
656 |
646 |
694 |
684 |
695 Window *FindWindowFromPt(int x, int y) |
685 Window *FindWindowFromPt(int x, int y) |
696 { |
686 { |
697 Window *w; |
687 Window *w; |
698 |
688 |
699 for(w=_last_window; w != _windows;) { |
689 for (w = _last_window; w != _windows;) { |
700 --w; |
690 --w; |
701 if (IS_INSIDE_1D(x, w->left, w->width) && |
691 if (IS_INSIDE_1D(x, w->left, w->width) && |
702 IS_INSIDE_1D(y, w->top, w->height)) |
692 IS_INSIDE_1D(y, w->top, w->height)) { |
703 return w; |
693 return w; |
|
694 } |
704 } |
695 } |
705 |
696 |
706 return NULL; |
697 return NULL; |
707 } |
698 } |
708 |
699 |
753 for (w = _last_window; w != _windows;) { |
744 for (w = _last_window; w != _windows;) { |
754 --w; |
745 --w; |
755 |
746 |
756 if (w->flags4&WF_TIMEOUT_MASK && !(--w->flags4&WF_TIMEOUT_MASK)) { |
747 if (w->flags4&WF_TIMEOUT_MASK && !(--w->flags4&WF_TIMEOUT_MASK)) { |
757 CallWindowEventNP(w, WE_TIMEOUT); |
748 CallWindowEventNP(w, WE_TIMEOUT); |
758 if (w->desc_flags & WDF_UNCLICK_BUTTONS) |
749 if (w->desc_flags & WDF_UNCLICK_BUTTONS) UnclickWindowButtons(w); |
759 UnclickWindowButtons(w); |
|
760 } |
750 } |
761 } |
751 } |
762 } |
752 } |
763 |
753 |
764 Window *GetCallbackWnd(void) |
754 Window *GetCallbackWnd(void) |
769 static void HandlePlacePresize(void) |
759 static void HandlePlacePresize(void) |
770 { |
760 { |
771 Window *w; |
761 Window *w; |
772 WindowEvent e; |
762 WindowEvent e; |
773 |
763 |
774 if (_special_mouse_mode != WSM_PRESIZE) |
764 if (_special_mouse_mode != WSM_PRESIZE) return; |
775 return; |
765 |
776 |
766 w = GetCallbackWnd(); |
777 if ((w = GetCallbackWnd()) == NULL) |
767 if (w == NULL) return; |
778 return; |
|
779 |
768 |
780 e.place.pt = GetTileBelowCursor(); |
769 e.place.pt = GetTileBelowCursor(); |
781 if (e.place.pt.x == -1) { |
770 if (e.place.pt.x == -1) { |
782 _thd.selend.x = -1; |
771 _thd.selend.x = -1; |
783 return; |
772 return; |
790 static bool HandleDragDrop(void) |
779 static bool HandleDragDrop(void) |
791 { |
780 { |
792 Window *w; |
781 Window *w; |
793 WindowEvent e; |
782 WindowEvent e; |
794 |
783 |
795 if (_special_mouse_mode != WSM_DRAGDROP) |
784 if (_special_mouse_mode != WSM_DRAGDROP) return true; |
796 return true; |
785 |
797 |
786 if (_left_button_down) return false; |
798 if (_left_button_down) |
|
799 return false; |
|
800 |
787 |
801 w = GetCallbackWnd(); |
788 w = GetCallbackWnd(); |
802 |
789 |
803 ResetObjectToPlace(); |
790 ResetObjectToPlace(); |
804 |
791 |
805 if (w) { |
792 if (w != NULL) { |
806 // send an event in client coordinates. |
793 // send an event in client coordinates. |
807 e.event = WE_DRAGDROP; |
794 e.event = WE_DRAGDROP; |
808 e.dragdrop.pt.x = _cursor.pos.x - w->left; |
795 e.dragdrop.pt.x = _cursor.pos.x - w->left; |
809 e.dragdrop.pt.y = _cursor.pos.y - w->top; |
796 e.dragdrop.pt.y = _cursor.pos.y - w->top; |
810 e.dragdrop.widget = GetWidgetFromPos(w, e.dragdrop.pt.x, e.dragdrop.pt.y); |
797 e.dragdrop.widget = GetWidgetFromPos(w, e.dragdrop.pt.x, e.dragdrop.pt.y); |
848 static Window *last_w = NULL; |
834 static Window *last_w = NULL; |
849 |
835 |
850 w = FindWindowFromPt(_cursor.pos.x, _cursor.pos.y); |
836 w = FindWindowFromPt(_cursor.pos.x, _cursor.pos.y); |
851 |
837 |
852 // We changed window, put a MOUSEOVER event to the last window |
838 // We changed window, put a MOUSEOVER event to the last window |
853 if (last_w && last_w != w) { |
839 if (last_w != NULL && last_w != w) { |
854 e.event = WE_MOUSEOVER; |
840 e.event = WE_MOUSEOVER; |
855 e.mouseover.pt.x = -1; |
841 e.mouseover.pt.x = -1; |
856 e.mouseover.pt.y = -1; |
842 e.mouseover.pt.y = -1; |
857 if (last_w->wndproc) |
843 if (last_w->wndproc) last_w->wndproc(last_w, &e); |
858 last_w->wndproc(last_w, &e); |
|
859 } |
844 } |
860 last_w = w; |
845 last_w = w; |
861 |
846 |
862 if (w) { |
847 if (w != NULL) { |
863 // send an event in client coordinates. |
848 // send an event in client coordinates. |
864 e.event = WE_MOUSEOVER; |
849 e.event = WE_MOUSEOVER; |
865 e.mouseover.pt.x = _cursor.pos.x - w->left; |
850 e.mouseover.pt.x = _cursor.pos.x - w->left; |
866 e.mouseover.pt.y = _cursor.pos.y - w->top; |
851 e.mouseover.pt.y = _cursor.pos.y - w->top; |
867 if (w->widget != NULL) { |
852 if (w->widget != NULL) { |
879 |
864 |
880 static bool HandleWindowDragging(void) |
865 static bool HandleWindowDragging(void) |
881 { |
866 { |
882 Window *w; |
867 Window *w; |
883 // Get out immediately if no window is being dragged at all. |
868 // Get out immediately if no window is being dragged at all. |
884 if (!_dragging_window) |
869 if (!_dragging_window) return true; |
885 return true; |
|
886 |
870 |
887 // Otherwise find the window... |
871 // Otherwise find the window... |
888 for (w = _windows; w != _last_window; w++) { |
872 for (w = _windows; w != _last_window; w++) { |
889 if (w->flags4 & WF_DRAGGING) { |
873 if (w->flags4 & WF_DRAGGING) { |
890 const Widget *t = &w->widget[1]; // the title bar ... ugh |
874 const Widget *t = &w->widget[1]; // the title bar ... ugh |
996 (v_right > _screen.width - 13 && nx + t->right > v_right)) { |
980 (v_right > _screen.width - 13 && nx + t->right > v_right)) { |
997 ny = v_bottom; |
981 ny = v_bottom; |
998 } else { |
982 } else { |
999 if (nx + t->left > v->left - 13 && |
983 if (nx + t->left > v->left - 13 && |
1000 nx + t->right < v_right + 13) { |
984 nx + t->right < v_right + 13) { |
1001 if (w->top >= v_bottom) |
985 if (w->top >= v_bottom) { |
1002 ny = v_bottom; |
986 ny = v_bottom; |
1003 else if (w->left < nx) |
987 } else if (w->left < nx) { |
1004 nx = v->left - 13 - t->left; |
988 nx = v->left - 13 - t->left; |
1005 else |
989 } else { |
1006 nx = v_right + 13 - t->right; |
990 nx = v_right + 13 - t->right; |
|
991 } |
1007 } |
992 } |
1008 } |
993 } |
1009 } |
994 } |
1010 } |
995 } |
1011 |
996 |
1031 |
1016 |
1032 x = _cursor.pos.x - _drag_delta.x; |
1017 x = _cursor.pos.x - _drag_delta.x; |
1033 y = _cursor.pos.y - _drag_delta.y; |
1018 y = _cursor.pos.y - _drag_delta.y; |
1034 |
1019 |
1035 /* X and Y has to go by step.. calculate it */ |
1020 /* X and Y has to go by step.. calculate it */ |
1036 if (w->resize.step_width > 1) |
1021 if (w->resize.step_width > 1) x = x - (x % w->resize.step_width); |
1037 x = x - (x % (int)w->resize.step_width); |
1022 |
1038 |
1023 if (w->resize.step_height > 1) y = y - (y % w->resize.step_height); |
1039 if (w->resize.step_height > 1) |
|
1040 y = y - (y % (int)w->resize.step_height); |
|
1041 |
1024 |
1042 /* Check if we don't go below the minimum set size */ |
1025 /* Check if we don't go below the minimum set size */ |
1043 if ((int)w->width + x < (int)w->resize.width) |
1026 if ((int)w->width + x < (int)w->resize.width) |
1044 x = w->resize.width - w->width; |
1027 x = w->resize.width - w->width; |
1045 if ((int)w->height + y < (int)w->resize.height) |
1028 if ((int)w->height + y < (int)w->resize.height) |
1046 y = w->resize.height - w->height; |
1029 y = w->resize.height - w->height; |
1047 |
1030 |
1048 /* Window already on size */ |
1031 /* Window already on size */ |
1049 if (x == 0 && y == 0) |
1032 if (x == 0 && y == 0) return false; |
1050 return false; |
|
1051 |
1033 |
1052 /* Now find the new cursor pos.. this is NOT _cursor, because |
1034 /* Now find the new cursor pos.. this is NOT _cursor, because |
1053 we move in steps. */ |
1035 we move in steps. */ |
1054 _drag_delta.x += x; |
1036 _drag_delta.x += x; |
1055 _drag_delta.y += y; |
1037 _drag_delta.y += y; |
1085 } |
1067 } |
1086 wi++; |
1068 wi++; |
1087 } |
1069 } |
1088 |
1070 |
1089 /* We resized at least 1 widget, so let's rezise the window totally */ |
1071 /* We resized at least 1 widget, so let's rezise the window totally */ |
1090 if (resize_width) |
1072 if (resize_width) w->width = x + w->width; |
1091 w->width = x + w->width; |
1073 if (resize_height) w->height = y + w->height; |
1092 if (resize_height) |
|
1093 w->height = y + w->height; |
|
1094 } |
1074 } |
1095 |
1075 |
1096 e.event = WE_RESIZE; |
1076 e.event = WE_RESIZE; |
1097 e.sizing.size.x = x + w->width; |
1077 e.sizing.size.x = x + w->width; |
1098 e.sizing.size.y = y + w->height; |
1078 e.sizing.size.y = y + w->height; |
1143 int i; |
1123 int i; |
1144 int pos; |
1124 int pos; |
1145 Scrollbar *sb; |
1125 Scrollbar *sb; |
1146 |
1126 |
1147 // Get out quickly if no item is being scrolled |
1127 // Get out quickly if no item is being scrolled |
1148 if (!_scrolling_scrollbar) |
1128 if (!_scrolling_scrollbar) return true; |
1149 return true; |
|
1150 |
1129 |
1151 // Find the scrolling window |
1130 // Find the scrolling window |
1152 for(w=_windows; w != _last_window; w++) { |
1131 for (w = _windows; w != _last_window; w++) { |
1153 if (w->flags4 & WF_SCROLL_MIDDLE) { |
1132 if (w->flags4 & WF_SCROLL_MIDDLE) { |
1154 // Abort if no button is clicked any more. |
1133 // Abort if no button is clicked any more. |
1155 if (!_left_button_down) { |
1134 if (!_left_button_down) { |
1156 w->flags4 &= ~WF_SCROLL_MIDDLE; |
1135 w->flags4 &= ~WF_SCROLL_MIDDLE; |
1157 SetWindowDirty(w); |
1136 SetWindowDirty(w); |
1187 { |
1166 { |
1188 Window *w; |
1167 Window *w; |
1189 ViewPort *vp; |
1168 ViewPort *vp; |
1190 int dx,dy, x, y, sub; |
1169 int dx,dy, x, y, sub; |
1191 |
1170 |
1192 if (!_scrolling_viewport) |
1171 if (!_scrolling_viewport) return true; |
1193 return true; |
|
1194 |
1172 |
1195 if (!_right_button_down) { |
1173 if (!_right_button_down) { |
1196 stop_capt:; |
1174 stop_capt:; |
1197 _cursor.fix_at = false; |
1175 _cursor.fix_at = false; |
1198 _scrolling_viewport = false; |
1176 _scrolling_viewport = false; |
1247 |
1225 |
1248 hx = (w->widget[4].right - w->widget[4].left) / 2; |
1226 hx = (w->widget[4].right - w->widget[4].left) / 2; |
1249 hy = (w->widget[4].bottom - w->widget[4].top ) / 2; |
1227 hy = (w->widget[4].bottom - w->widget[4].top ) / 2; |
1250 hvx = hx * -4 + hy * 8; |
1228 hvx = hx * -4 + hy * 8; |
1251 hvy = hx * 4 + hy * 8; |
1229 hvy = hx * 4 + hy * 8; |
1252 if (x < -hvx) { x = -hvx; sub = 0; } |
1230 if (x < -hvx) { |
1253 if (x > (int)MapMaxX() * 16 - hvx) { x = MapMaxX() * 16 - hvx; sub = 0; } |
1231 x = -hvx; |
1254 if (y < -hvy) { y = -hvy; sub = 0; } |
1232 sub = 0; |
1255 if (y > (int)MapMaxY() * 16 - hvy) { y = MapMaxY() * 16 - hvy; sub = 0; } |
1233 } |
|
1234 if (x > (int)MapMaxX() * 16 - hvx) { |
|
1235 x = MapMaxX() * 16 - hvx; |
|
1236 sub = 0; |
|
1237 } |
|
1238 if (y < -hvy) { |
|
1239 y = -hvy; |
|
1240 sub = 0; |
|
1241 } |
|
1242 if (y > (int)MapMaxY() * 16 - hvy) { |
|
1243 y = MapMaxY() * 16 - hvy; |
|
1244 sub = 0; |
|
1245 } |
1256 |
1246 |
1257 WP(w,smallmap_d).scroll_x = x; |
1247 WP(w,smallmap_d).scroll_x = x; |
1258 WP(w,smallmap_d).scroll_y = y; |
1248 WP(w,smallmap_d).scroll_y = y; |
1259 WP(w,smallmap_d).subscroll = sub; |
1249 WP(w,smallmap_d).subscroll = sub; |
1260 |
1250 |
1267 |
1257 |
1268 static Window *MaybeBringWindowToFront(Window *w) |
1258 static Window *MaybeBringWindowToFront(Window *w) |
1269 { |
1259 { |
1270 Window *u; |
1260 Window *u; |
1271 |
1261 |
1272 if (w->window_class == WC_MAIN_WINDOW || IsVitalWindow(w) || |
1262 if (w->window_class == WC_MAIN_WINDOW || |
1273 w->window_class == WC_TOOLTIPS || w->window_class == WC_DROPDOWN_MENU) |
1263 IsVitalWindow(w) || |
1274 return w; |
1264 w->window_class == WC_TOOLTIPS || |
|
1265 w->window_class == WC_DROPDOWN_MENU) { |
|
1266 return w; |
|
1267 } |
1275 |
1268 |
1276 for (u = w; ++u != _last_window;) { |
1269 for (u = w; ++u != _last_window;) { |
1277 if (u->window_class == WC_MAIN_WINDOW || IsVitalWindow(u) || |
1270 if (u->window_class == WC_MAIN_WINDOW || |
1278 u->window_class == WC_TOOLTIPS || u->window_class == WC_DROPDOWN_MENU) |
1271 IsVitalWindow(u) || |
1279 continue; |
1272 u->window_class == WC_TOOLTIPS || |
|
1273 u->window_class == WC_DROPDOWN_MENU) { |
|
1274 continue; |
|
1275 } |
1280 |
1276 |
1281 if (w->left + w->width <= u->left || |
1277 if (w->left + w->width <= u->left || |
1282 u->left + u->width <= w->left || |
1278 u->left + u->width <= w->left || |
1283 w->top + w->height <= u->top || |
1279 w->top + w->height <= u->top || |
1284 u->top + u->height <= w->top) |
1280 u->top + u->height <= w->top) { |
1285 continue; |
1281 continue; |
|
1282 } |
1286 |
1283 |
1287 return BringWindowToFront(w); |
1284 return BringWindowToFront(w); |
1288 } |
1285 } |
1289 |
1286 |
1290 return w; |
1287 return w; |
1335 we.keypress.ascii = key & 0xFF; |
1332 we.keypress.ascii = key & 0xFF; |
1336 we.keypress.keycode = key >> 16; |
1333 we.keypress.keycode = key >> 16; |
1337 we.keypress.cont = true; |
1334 we.keypress.cont = true; |
1338 |
1335 |
1339 // check if we have a query string window open before allowing hotkeys |
1336 // check if we have a query string window open before allowing hotkeys |
1340 if(FindWindowById(WC_QUERY_STRING, 0)!=NULL || FindWindowById(WC_SEND_NETWORK_MSG, 0)!=NULL || FindWindowById(WC_CONSOLE, 0)!=NULL || FindWindowById(WC_SAVELOAD, 0)!=NULL) |
1337 if (FindWindowById(WC_QUERY_STRING, 0) != NULL || |
|
1338 FindWindowById(WC_SEND_NETWORK_MSG, 0) != NULL || |
|
1339 FindWindowById(WC_CONSOLE, 0) != NULL || |
|
1340 FindWindowById(WC_SAVELOAD, 0) != NULL) { |
1341 query_open = true; |
1341 query_open = true; |
|
1342 } |
1342 |
1343 |
1343 // Call the event, start with the uppermost window. |
1344 // Call the event, start with the uppermost window. |
1344 for(w=_last_window; w != _windows;) { |
1345 for (w = _last_window; w != _windows;) { |
1345 --w; |
1346 --w; |
1346 // if a query window is open, only call the event for certain window types |
1347 // if a query window is open, only call the event for certain window types |
1347 if(query_open && w->window_class!=WC_QUERY_STRING && w->window_class!=WC_SEND_NETWORK_MSG && w->window_class!=WC_CONSOLE && w->window_class!=WC_SAVELOAD) |
1348 if (query_open && |
|
1349 w->window_class != WC_QUERY_STRING && |
|
1350 w->window_class != WC_SEND_NETWORK_MSG && |
|
1351 w->window_class != WC_CONSOLE && |
|
1352 w->window_class != WC_SAVELOAD) { |
1348 continue; |
1353 continue; |
|
1354 } |
1349 w->wndproc(w, &we); |
1355 w->wndproc(w, &we); |
1350 if (!we.keypress.cont) |
1356 if (!we.keypress.cont) break; |
1351 break; |
|
1352 } |
1357 } |
1353 |
1358 |
1354 if (we.keypress.cont) { |
1359 if (we.keypress.cont) { |
1355 w = FindWindowById(WC_MAIN_TOOLBAR, 0); |
1360 w = FindWindowById(WC_MAIN_TOOLBAR, 0); |
1356 // When there is no toolbar w is null, check for that |
1361 // When there is no toolbar w is null, check for that |
1368 ViewPort *vp; |
1373 ViewPort *vp; |
1369 |
1374 |
1370 DecreaseWindowCounters(); |
1375 DecreaseWindowCounters(); |
1371 HandlePlacePresize(); |
1376 HandlePlacePresize(); |
1372 UpdateTileSelection(); |
1377 UpdateTileSelection(); |
1373 if (!VpHandlePlaceSizingDrag()) |
1378 if (!VpHandlePlaceSizingDrag()) return; |
1374 return; |
1379 if (!HandleDragDrop()) return; |
1375 |
1380 if (!HandlePopupMenu()) return; |
1376 if (!HandleDragDrop()) |
1381 if (!HandleWindowDragging()) return; |
1377 return; |
1382 if (!HandleScrollbarScrolling()) return; |
1378 |
1383 if (!HandleViewportScroll()) return; |
1379 if (!HandlePopupMenu()) |
1384 if (!HandleMouseOver()) return; |
1380 return; |
|
1381 |
|
1382 if (!HandleWindowDragging()) |
|
1383 return; |
|
1384 |
|
1385 if (!HandleScrollbarScrolling()) |
|
1386 return; |
|
1387 |
|
1388 if (!HandleViewportScroll()) |
|
1389 return; |
|
1390 |
|
1391 if (!HandleMouseOver()) |
|
1392 return; |
|
1393 |
1385 |
1394 x = _cursor.pos.x; |
1386 x = _cursor.pos.x; |
1395 y = _cursor.pos.y; |
1387 y = _cursor.pos.y; |
1396 |
1388 |
1397 |
1389 |
1420 } |
1412 } |
1421 return; |
1413 return; |
1422 } |
1414 } |
1423 |
1415 |
1424 w = FindWindowFromPt(x, y); |
1416 w = FindWindowFromPt(x, y); |
1425 if (w == NULL) |
1417 if (w == NULL) return; |
1426 return; |
|
1427 w = MaybeBringWindowToFront(w); |
1418 w = MaybeBringWindowToFront(w); |
1428 vp = IsPtInWindowViewport(w, x, y); |
1419 vp = IsPtInWindowViewport(w, x, y); |
1429 if (vp != NULL) { |
1420 if (vp != NULL) { |
1430 if (_game_mode == GM_MENU) |
1421 if (_game_mode == GM_MENU) return; |
1431 return; |
|
1432 |
1422 |
1433 // only allow zooming in-out in main window, or in viewports |
1423 // only allow zooming in-out in main window, or in viewports |
1434 if ( mousewheel && !(w->flags4 & WF_DISABLE_VP_SCROLL) && |
1424 if (mousewheel && |
1435 (w->window_class == WC_MAIN_WINDOW || w->window_class == WC_EXTRA_VIEW_PORT) ) { |
1425 !(w->flags4 & WF_DISABLE_VP_SCROLL) && ( |
|
1426 w->window_class == WC_MAIN_WINDOW || |
|
1427 w->window_class == WC_EXTRA_VIEW_PORT |
|
1428 )) { |
1436 ZoomInOrOutToCursorWindow(mousewheel < 0,w); |
1429 ZoomInOrOutToCursorWindow(mousewheel < 0,w); |
1437 } |
1430 } |
1438 |
1431 |
1439 if (click == 1) { |
1432 if (click == 1) { |
1440 DEBUG(misc, 2) ("cursor: 0x%X (%d)", _cursor.sprite, _cursor.sprite); |
1433 DEBUG(misc, 2) ("cursor: 0x%X (%d)", _cursor.sprite, _cursor.sprite); |
1507 void UpdateWindows(void) |
1500 void UpdateWindows(void) |
1508 { |
1501 { |
1509 Window *w; |
1502 Window *w; |
1510 int t; |
1503 int t; |
1511 |
1504 |
1512 |
1505 t = _we4_timer + 1; |
1513 if ((t=_we4_timer+1) >= 100) { |
1506 if (t >= 100) { |
1514 for(w = _last_window; w != _windows;) { |
1507 for (w = _last_window; w != _windows;) { |
1515 w--; |
1508 w--; |
1516 CallWindowEventNP(w, WE_4); |
1509 CallWindowEventNP(w, WE_4); |
1517 } |
1510 } |
1518 t = 0; |
1511 t = 0; |
1519 } |
1512 } |
1520 _we4_timer = t; |
1513 _we4_timer = t; |
1521 |
1514 |
1522 for(w = _last_window; w != _windows;) { |
1515 for (w = _last_window; w != _windows;) { |
1523 w--; |
1516 w--; |
1524 if (w->flags4 & WF_WHITE_BORDER_MASK) { |
1517 if (w->flags4 & WF_WHITE_BORDER_MASK) { |
1525 w->flags4 -= WF_WHITE_BORDER_ONE; |
1518 w->flags4 -= WF_WHITE_BORDER_ONE; |
1526 if (!(w->flags4 & WF_WHITE_BORDER_MASK)) { |
1519 if (!(w->flags4 & WF_WHITE_BORDER_MASK)) { |
1527 SetWindowDirty(w); |
1520 SetWindowDirty(w); |
1544 int GetMenuItemIndex(const Window *w, int x, int y) |
1536 int GetMenuItemIndex(const Window *w, int x, int y) |
1545 { |
1537 { |
1546 if ((x -= w->left) >= 0 && x < w->width && (y -= w->top + 1) >= 0) { |
1538 if ((x -= w->left) >= 0 && x < w->width && (y -= w->top + 1) >= 0) { |
1547 y /= 10; |
1539 y /= 10; |
1548 |
1540 |
1549 if (y < WP(w,menu_d).item_count && !HASBIT(WP(w,menu_d).disabled_items, y)) |
1541 if (y < WP(w, const menu_d).item_count && |
|
1542 !HASBIT(WP(w, const menu_d).disabled_items, y)) { |
1550 return y; |
1543 return y; |
|
1544 } |
1551 } |
1545 } |
1552 return -1; |
1546 return -1; |
1553 } |
1547 } |
1554 |
1548 |
1555 void InvalidateWindow(byte cls, WindowNumber number) |
1549 void InvalidateWindow(byte cls, WindowNumber number) |
1556 { |
1550 { |
1557 Window *w; |
1551 Window *w; |
1558 |
1552 |
1559 for(w=_windows; w!=_last_window; w++) { |
1553 for (w = _windows; w != _last_window; w++) { |
1560 if (w->window_class==cls && w->window_number==number) |
1554 if (w->window_class == cls && w->window_number == number) SetWindowDirty(w); |
1561 SetWindowDirty(w); |
|
1562 } |
1555 } |
1563 } |
1556 } |
1564 |
1557 |
1565 void InvalidateWidget(const Window* w, byte widget_index) |
1558 void InvalidateWidget(const Window* w, byte widget_index) |
1566 { |
1559 { |
1574 |
1567 |
1575 void InvalidateWindowWidget(byte cls, WindowNumber number, byte widget_index) |
1568 void InvalidateWindowWidget(byte cls, WindowNumber number, byte widget_index) |
1576 { |
1569 { |
1577 const Window* w; |
1570 const Window* w; |
1578 |
1571 |
1579 for(w=_windows; w!=_last_window; w++) { |
1572 for (w = _windows; w != _last_window; w++) { |
1580 if (w->window_class==cls && w->window_number==number) { |
1573 if (w->window_class == cls && w->window_number == number) { |
1581 InvalidateWidget(w, widget_index); |
1574 InvalidateWidget(w, widget_index); |
1582 } |
1575 } |
1583 } |
1576 } |
1584 } |
1577 } |
1585 |
1578 |
1586 void InvalidateWindowClasses(byte cls) |
1579 void InvalidateWindowClasses(byte cls) |
1587 { |
1580 { |
1588 const Window* w; |
1581 const Window* w; |
1589 for(w=_windows; w!=_last_window; w++) { |
1582 |
1590 if (w->window_class==cls) |
1583 for (w = _windows; w != _last_window; w++) { |
1591 SetWindowDirty(w); |
1584 if (w->window_class == cls) SetWindowDirty(w); |
1592 } |
1585 } |
1593 } |
1586 } |
1594 |
1587 |
1595 |
1588 |
1596 void CallWindowTickEvent(void) |
1589 void CallWindowTickEvent(void) |
1597 { |
1590 { |
1598 Window *w; |
1591 Window *w; |
1599 for(w=_last_window; w != _windows;) { |
1592 |
|
1593 for (w = _last_window; w != _windows;) { |
1600 --w; |
1594 --w; |
1601 CallWindowEventNP(w, WE_TICK); |
1595 CallWindowEventNP(w, WE_TICK); |
1602 } |
1596 } |
1603 } |
1597 } |
1604 |
1598 |
1605 void DeleteNonVitalWindows(void) |
1599 void DeleteNonVitalWindows(void) |
1606 { |
1600 { |
1607 Window *w; |
1601 Window *w; |
1608 for(w=_windows; w!=_last_window;) { |
1602 |
|
1603 for (w = _windows; w != _last_window;) { |
1609 if (w->window_class != WC_MAIN_WINDOW && |
1604 if (w->window_class != WC_MAIN_WINDOW && |
1610 w->window_class != WC_SELECT_GAME && |
1605 w->window_class != WC_SELECT_GAME && |
1611 w->window_class != WC_MAIN_TOOLBAR && |
1606 w->window_class != WC_MAIN_TOOLBAR && |
1612 w->window_class != WC_STATUS_BAR && |
1607 w->window_class != WC_STATUS_BAR && |
1613 w->window_class != WC_TOOLBAR_MENU && |
1608 w->window_class != WC_TOOLBAR_MENU && |
1627 * then, does a little hacked loop of closing all stickied windows. Note |
1622 * then, does a little hacked loop of closing all stickied windows. Note |
1628 * that standard windows (status bar, etc.) are not stickied, so these aren't affected */ |
1623 * that standard windows (status bar, etc.) are not stickied, so these aren't affected */ |
1629 void DeleteAllNonVitalWindows(void) |
1624 void DeleteAllNonVitalWindows(void) |
1630 { |
1625 { |
1631 Window *w; |
1626 Window *w; |
|
1627 |
1632 // Delete every window except for stickied ones |
1628 // Delete every window except for stickied ones |
1633 DeleteNonVitalWindows(); |
1629 DeleteNonVitalWindows(); |
1634 // Delete all sticked windows |
1630 // Delete all sticked windows |
1635 for (w = _windows; w != _last_window;) { |
1631 for (w = _windows; w != _last_window;) { |
1636 if (w->flags4 & WF_STICKY) { |
1632 if (w->flags4 & WF_STICKY) { |
1666 |
1662 |
1667 void RelocateAllWindows(int neww, int newh) |
1663 void RelocateAllWindows(int neww, int newh) |
1668 { |
1664 { |
1669 Window *w; |
1665 Window *w; |
1670 |
1666 |
1671 for(w=_windows; w!= _last_window ;w++) { |
1667 for (w = _windows; w != _last_window; w++) { |
1672 int left, top; |
1668 int left, top; |
1673 |
1669 |
1674 if (w->window_class == WC_MAIN_WINDOW) { |
1670 if (w->window_class == WC_MAIN_WINDOW) { |
1675 ViewPort *vp = w->viewport; |
1671 ViewPort *vp = w->viewport; |
1676 vp->width = w->width = neww; |
1672 vp->width = w->width = neww; |