X-Git-Url: https://plomlompom.com/repos/foo.html?a=blobdiff_plain;f=src%2Fclient%2Fwincontrol.c;h=eb9270b411130e5f4ce38471de247a817060857c;hb=ea9b56e85af64ae816c5faea045ffdd004d56472;hp=17d80ae7f961d04db75e4c280f7f006182b1e10f;hpb=f9d5829b125ef2df8d63bc08761be33f93c65691;p=plomrogue
diff --git a/src/client/wincontrol.c b/src/client/wincontrol.c
index 17d80ae..eb9270b 100644
--- a/src/client/wincontrol.c
+++ b/src/client/wincontrol.c
@@ -1,4 +1,9 @@
-/* src/client/wincontrol.c */
+/* src/client/wincontrol.c
+ *
+ * This file is part of PlomRogue. PlomRogue is licensed under the GPL version 3
+ * or any later version. For details on its copyright, license, and warranties,
+ * see the file NOTICE in the root directory of the PlomRogue source package.
+ */
#include "wincontrol.h"
#include /* getmaxx(), getmaxy(), wresize() */
@@ -7,10 +12,9 @@
#include /* sprintf() */
#include /* free() */
#include /* memcpy(), memset(), strchr(), strlen() */
-#include "../common/rexit.h" /* exit_err() */
+#include "../common/rexit.h" /* exit_err(), exit_trouble() */
#include "../common/try_malloc.h" /* try_malloc() */
-#include "../common/yx_uint16.h" /* struct yx_uint16 */
-#include "windows.h" /* struct Win, get_win_by_id(), get_win_pos_in_order() */
+#include "windows.h" /* Win,yx_uint16, get_win_by_id(),get_win_pos_in_order() */
#include "world.h" /* global world */
@@ -96,54 +100,58 @@ static void update_wins(struct Win * w)
static void place_win(struct Win * w)
{
+ uint8_t sep = 1; /* Width of inter-window borders and title bars. */
+
/* If w is first window, it goes into the top left corner. */
w->start.x = 0;
- w->start.y = 1; /* Leave space for title bar. */
+ w->start.y = 0 + sep;
struct Win * w_prev = get_win_before(w->id);
if (w_prev)
{
- /* If not, fit w's top left to top right of last top predecessor. */
+ /* If not, get w's next predecessor starting a new stack on the screen
+ * top, fit w's top left corner to that predecessor's top right corner.
+ */
struct Win * w_top = w_prev;
- for (;
- w_top->start.y != 1;
- w_top = get_win_before(w_top->id));
- w->start.x = w_top->start.x + w_top->frame_size.x + 1;
+ for (; w_top->start.y != 0 + sep; w_top = get_win_before(w_top->id));
+ w->start.x = w_top->start.x + w_top->frame_size.x + sep;
- /* Fit w's top left to bottom left of its ->prev if enough space. */
- uint16_t w_prev_maxy = w_prev->start.y + w_prev->frame_size.y;
+ /* If enough space is found below w's predecessor, fit w's top left
+ * corner to that predecessor's bottom left corner.
+ */
+ uint16_t next_free_y = w_prev->start.y + w_prev->frame_size.y + sep;
if ( w->frame_size.x <= w_prev->frame_size.x
- && w->frame_size.y < world.winDB.v_screen_size.y - w_prev_maxy)
+ && w->frame_size.y <= world.winDB.v_screen_size.y - next_free_y)
{
w->start.x = w_prev->start.x;
- w->start.y = w_prev_maxy + 1;
+ w->start.y = next_free_y;
return;
}
- /* Failing that, try to fit w' top left to the top right of the last
- * predecessor w_test 1) not followed by windows with a left corner
- * further rightwards than its own 2) with enough space rightwards for w
- * until the bottom right of w_thr directly throning over it 3) and with
- * this same space extending far enough to the bottom for fitting in w.
+ /* If that fails, try to fit w's top left corner to the top right corner
+ * of its next predecessor w_test 1) below w_top (w's next predecessor
+ * starting a new stack on the screen top) 2) and the most rightward
+ * lower neighbor of a window w_high, itself throning over enough free
+ * space for w to fit below it, rightwards of its lower neighbor w_test.
*/
struct Win * w_test = w_prev;
- struct Win * w_thr;
+ struct Win * w_high;
while (w_test != w_top)
{
- for (w_thr = get_win_before(w_test->id);
- w_test->start.y <= w_thr->start.y;
- w_thr = get_win_before(w_thr->id));
- uint16_t w_thr_bottom = w_thr->start.y + w_thr->frame_size.y;
- uint16_t free_width = (w_thr->start.x + w_thr->frame_size.x)
- - (w_test->start.x + w_test->frame_size.x);
- if ( w->frame_size.y < world.winDB.v_screen_size.y - w_thr_bottom
- && w->frame_size.x < free_width)
+ for (w_high = get_win_before(w_test->id); /* Walk down chain */
+ w_test->start.y <= w_high->start.y; /* until w_high starts */
+ w_high = get_win_before(w_high->id)); /* higher than w_test. */
+ next_free_y = w_high->start.y + w_high->frame_size.y + sep;
+ uint16_t first_free_x = w_test->start.x + w_test->frame_size.x +sep;
+ uint16_t last_free_x = w_high->start.x + w_high->frame_size.x;
+ if ( w->frame_size.y <= world.winDB.v_screen_size.y - next_free_y
+ && w->frame_size.x <= last_free_x - first_free_x)
{
- w->start.x = w_test->start.x + w_test->frame_size.x + 1;
- w->start.y = w_thr_bottom + 1;
+ w->start.x = first_free_x;
+ w->start.y = next_free_y;
break;
}
- w_test = w_thr;
+ w_test = w_high;
}
}
}
@@ -174,9 +182,8 @@ static void set_win_target_size(struct Win * w)
static void append_win(struct Win * w)
{
- char * f_name = "append_win()";
uint8_t old_size = strlen(world.winDB.order) + 1;
- char * new_order = try_malloc(old_size + 1, f_name);
+ char * new_order = try_malloc(old_size + 1, __func__);
memcpy(new_order, world.winDB.order, old_size - 1);
new_order[old_size - 1] = w->id;
new_order[old_size] = '\0';
@@ -190,14 +197,14 @@ static void append_win(struct Win * w)
static void suspend_win(struct Win * w)
{
- char * f_name = "suspend_win()";
uint8_t new_size = strlen(world.winDB.order);
- char * new_order = try_malloc(new_size, f_name);
+ char * new_order = try_malloc(new_size, __func__);
uint8_t i = get_win_pos_in_order(w->id);
char next_char = world.winDB.order[i + 1];
world.winDB.order[i] = '\0';
char * second_part = &world.winDB.order[i + 1];
- sprintf(new_order, "%s%s", world.winDB.order, second_part);
+ int test = sprintf(new_order, "%s%s", world.winDB.order, second_part);
+ exit_trouble(test < 0, __func__, "sprintf");
free(world.winDB.order);
world.winDB.order = new_order;
world.winDB.active = world.winDB.order[i];
@@ -218,7 +225,7 @@ static void suspend_win(struct Win * w)
extern void toggle_window(char id)
{
struct Win * win = get_win_by_id(id);
- if (NULL == strchr(world.winDB.order, id))
+ if (!strchr(world.winDB.order, id))
{
append_win(win);
return;
@@ -328,7 +335,7 @@ extern void shift_active_win(char dir)
uint8_t len_order = strlen(world.winDB.order);
if (1 < len_order)
{
- char tmp[len_order + 1];
+ char * tmp = try_malloc(len_order + 1, __func__);
tmp[len_order] = '\0';
uint8_t pos = get_win_pos_in_order(world.winDB.active);
if ('f' == dir)
@@ -359,6 +366,7 @@ extern void shift_active_win(char dir)
world.winDB.order[pos - 1] = world.winDB.active;
}
}
+ free(tmp);
update_wins(get_win_by_id(world.winDB.order[0]));
}
}