home · contact · privacy
draw_all_wins() returns error code of its draw_scroll_hint() uses.
[plomrogue] / src / windows.c
index 8af2ba259411500fa73d3c22ce4483d458bb4051..74fb6cfd53c5407a516b658ccf1bc1bcda6b4039 100644 (file)
@@ -58,6 +58,12 @@ static void draw_wins_bordercorners(struct Win * w, WINDOW * pad);
 
 
 
+/* Shift active window forwards / backwards in window chain. */
+static void shift_win_forward(struct WinMeta * wmeta);
+static void shift_win_backward(struct WinMeta * wmeta);
+
+
+
 static uint8_t refit_pad(struct WinMeta * wmeta)
 {
     /* Determine rightmost window column. */
@@ -269,6 +275,88 @@ static void draw_wins_bordercorners(struct Win * w, WINDOW * pad)
 
 
 
+static void shift_win_forward(struct WinMeta * wmeta)
+{
+    if (wmeta->active == wmeta->chain_end)
+    {
+        wmeta->chain_end = wmeta->active->prev;
+        wmeta->chain_end->next = 0;
+        wmeta->active->next = wmeta->chain_start;
+        wmeta->active->next->prev = wmeta->active;
+        wmeta->chain_start = wmeta->active;
+        wmeta->chain_start->prev = 0;
+    }
+    else
+    {
+        struct Win * old_prev = wmeta->active->prev;
+        struct Win * old_next = wmeta->active->next;
+        if (wmeta->chain_end == wmeta->active->next)
+        {
+            wmeta->chain_end = wmeta->active;
+            wmeta->active->next = 0;
+        }
+        else
+        {
+            wmeta->active->next = old_next->next;
+            wmeta->active->next->prev = wmeta->active;
+        }
+        if (wmeta->chain_start == wmeta->active)
+        {
+            wmeta->chain_start = old_next;
+        }
+        else
+        {
+            old_prev->next = old_next;
+        }
+        old_next->prev = old_prev;
+        old_next->next = wmeta->active;
+        wmeta->active->prev = old_next;
+    }
+}
+
+
+
+static void shift_win_backward(struct WinMeta * wmeta)
+{
+    if (wmeta->active == wmeta->chain_start)
+    {
+        wmeta->chain_start = wmeta->active->next;
+        wmeta->chain_start->prev = 0;
+        wmeta->active->prev = wmeta->chain_end;
+        wmeta->active->prev->next = wmeta->active;
+        wmeta->chain_end = wmeta->active;
+        wmeta->chain_end->next = 0;
+    }
+    else
+    {
+        struct Win * old_prev = wmeta->active->prev;
+        struct Win * old_next = wmeta->active->next;
+        if (wmeta->chain_start == wmeta->active->prev)
+        {
+            wmeta->chain_start = wmeta->active;
+            wmeta->active->prev = 0;
+        }
+        else
+        {
+            wmeta->active->prev = old_prev->prev;
+            wmeta->active->prev->next = wmeta->active;
+        }
+        if (wmeta->chain_end == wmeta->active)
+        {
+            wmeta->chain_end = old_prev;
+        }
+        else
+        {
+            old_next->prev = old_prev;
+        }
+        old_prev->next = old_next;
+        old_prev->prev = wmeta->active;
+        wmeta->active->next = old_prev;
+    }
+}
+
+
+
 extern uint8_t init_win_meta(WINDOW * screen, struct WinMeta * wmeta)
 {
     wmeta->screen              = screen;
@@ -445,110 +533,28 @@ extern void cycle_active_win(struct WinMeta * wmeta, char dir)
 
 
 
-extern uint8_t shift_active_win(struct WinMeta * wmeta, char dir)
+extern void shift_active_win(struct WinMeta * wmeta, char dir)
 {
-    if (0 != wmeta->active                        /* No shifting with less    */
-        && wmeta->chain_start != wmeta->chain_end /* than one window visible. */
-        && (dir == 'f' || dir == 'b'))
+    if (   0 == wmeta->active                     /* No shifting with less    */
+        || wmeta->chain_start == wmeta->chain_end /* than two windows visible */
+        || (dir != 'f' && dir != 'b'))            /* or wrong direction char. */
     {
-        struct Win * w_shift = wmeta->active, * w_p, * w_p_next;
-
-        /* Check if shifting will lead to wrapping. */
-        char wrap = 0;
-        if (   (dir == 'f' && w_shift == wmeta->chain_end)
-            || (dir == 'b' && w_shift == wmeta->chain_start))
-        {
-            wrap = 1;
-        }
-
-        /* Suspend all visible windows, remember their order in wins[]. */
-        uint16_t i, i_max;
-        for (w_p  = wmeta->chain_start, i_max = 1;
-             w_p != wmeta->chain_end;
-             w_p  = w_p->next)
-        {
-            i_max++;
-        }
-        struct Win ** wins = malloc(i_max * sizeof(struct Win *));
-        if (NULL == wins)
-        {
-            return 1;
-        }
-        for (i = 0, w_p = wmeta->chain_start;
-             i < i_max;
-             i++)
-        {
-            w_p_next = w_p->next;
-            suspend_win(wmeta, w_p);
-            wins[i] = w_p;
-            w_p = w_p_next;
-        }
-
-        /* Re-append all previously visible windows in the new order. */
-        if (wrap)
-        {
-            if (dir == 'f')
-            {
-                if (0 != append_win(wmeta, w_shift))
-                {
-                    return 1;
-                }
-                for (i = 0; i < i_max - 1; i++)
-                {
-                    if (0 != append_win(wmeta, wins[i]))
-                    {
-                        return 1;
-                    }
-                }
-            }
-            else
-            {
-                for (i = 1; i < i_max; i++)
-                {
-                    if (0 != append_win(wmeta, wins[i]))
-                    {
-                        return 1;
-                    }
-                }
-                if (0 != append_win(wmeta, w_shift))
-                {
-                    return 1;
-                }
-            }
-        }
-        else
-        {
-            for (i = 0; i < i_max; i++)
-            {
-                if (   (dir == 'f' && w_shift == wins[i])
-                    || (dir == 'b' && w_shift == wins[i+1]))
-                {
-                    if (   0 != append_win(wmeta, wins[i+1])
-                        || 0 != append_win(wmeta, wins[i]))
-                    {
-                        return 1;
-                    }
-                    i++;
-                }
-                else
-                {
-                    if (0 != append_win(wmeta, wins[i]))
-                    {
-                        return 1;
-                    }
-                }
-            }
-        }
-        free(wins);
-
-        wmeta->active = w_shift;  /* Otherwise lastly appended win is active. */
+        return;
     }
-    return 0;
+    if ('f' == dir)
+    {
+        shift_win_forward(wmeta);
+    }
+    else
+    {
+        shift_win_backward(wmeta);
+    }
+    update_wins(wmeta, wmeta->chain_start);
 }
 
 
 
-extern void draw_all_wins(struct WinMeta * wmeta)
+extern uint8_t draw_all_wins(struct WinMeta * wmeta)
 {
     /* Empty everything before filling it a-new. */
     erase();
@@ -566,17 +572,23 @@ extern void draw_all_wins(struct WinMeta * wmeta)
         /* Draw virtual screen scroll hints. */
         if (wmeta->pad_offset > 0)
         {
-            draw_scroll_hint(&wmeta->padframe,
-                             wmeta->pad_offset, wmeta->pad_offset + 1, '<');
+            if (draw_scroll_hint(&wmeta->padframe,
+                                 wmeta->pad_offset, wmeta->pad_offset + 1, '<'))
+            {
+                return 1;
+            }
         }
         if (wmeta->pad_offset + wmeta->padframe.size.x
             < getmaxx(wmeta->padframe.curses_win) - 1)
         {
-            draw_scroll_hint(&wmeta->padframe,
-                             wmeta->pad_offset + wmeta->padframe.size.x - 1,
-                             getmaxx(wmeta->padframe.curses_win)
-                             - (wmeta->pad_offset + wmeta->padframe.size.x),
-                             '>');
+            if (draw_scroll_hint(&wmeta->padframe,
+                                 wmeta->pad_offset + wmeta->padframe.size.x - 1,
+                                 getmaxx(wmeta->padframe.curses_win)
+                                 - (wmeta->pad_offset + wmeta->padframe.size.x),
+                                 '>'))
+            {
+                return 1;
+            }
         }
 
         /* Write virtual screen segment to be shown on physical screen into */
@@ -587,6 +599,7 @@ extern void draw_all_wins(struct WinMeta * wmeta)
 
     /* Only at the end write accumulated changes to the physical screen. */
     doupdate();
+    return 0;
 }