]> git.vomp.tv Git - vompclient.git/commitdiff
New GUI code
authorChris Tallon <chris@vomp.tv>
Wed, 9 Nov 2005 02:26:56 +0000 (02:26 +0000)
committerChris Tallon <chris@vomp.tv>
Wed, 9 Nov 2005 02:26:56 +0000 (02:26 +0000)
25 files changed:
Makefile
box.cc
box.h
command.cc
main.cc
message.h
osd.cc
osd.h
region.cc [new file with mode: 0644]
region.h [new file with mode: 0644]
surface.cc
surface.h
vchannellist.cc
view.cc
viewman.cc
viewman.h
vlivebanner.cc
vrecordinglist.cc
vrecordingmenu.cc
vserverselect.cc
vvideolive.cc
vwelcome.cc
widget.cc
wjpeg.cc
wselectlist.cc

index 2ab18e585fc18ccad3d9c4bc9335e3ce18155964..d3ed82baafddf5bdc1bea9edd985dcb9470e0ecd 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -16,7 +16,7 @@ OBJECTS = main.o command.o log.o remote.o led.o mtd.o video.o audio.o tcp.o dire
           recording.o channel.o message.o playervideo.o playerradio.o messagequeue.o \
           view.o vinfo.o vwallpaper.o vvolume.o vrecordinglist.o vlivebanner.o vmute.o \
           vrecordingmenu.o vquestion.o vchannellist.o vwelcome.o vvideolive.o vvideorec.o vradiolive.o \
-          vchannelselect.o vserverselect.o colour.o vconnect.o voptions.o \
+          vchannelselect.o vserverselect.o colour.o vconnect.o voptions.o region.o \
           widget.o wselectlist.o wjpeg.o wsymbol.o wbutton.o woptionbox.o i18n.o \
           fonts/helvB24.o fonts/helvB18.o
 
diff --git a/box.cc b/box.cc
index dc28da5b6bd33a4b34d94e233563bfb01e757ff6..ef441a429e3e71b8e0094c884daa286430ad3e69 100644 (file)
--- a/box.cc
+++ b/box.cc
@@ -24,11 +24,11 @@ char Box::numBoxes = 0;
 
 Box::Box()
 {
-  height = 0;
-  width = 0;
+  area.x = 0;
+  area.y = 0;
+  area.w = 0;
+  area.h = 0;
 
-  screenX = 0;
-  screenY = 0;
   offsetX = 0;
   offsetY = 0;
 
@@ -50,8 +50,8 @@ void Box::draw()
 
 void Box::setScreenPos(int x, int y)
 {
-  screenX = x;
-  screenY = y;
+  area.x = x;
+  area.y = y;
 }
 
 void Box::setSurfaceOffset(UINT x, UINT y)
@@ -60,38 +60,53 @@ void Box::setSurfaceOffset(UINT x, UINT y)
   offsetY = y;
 }
 
-void Box::show(int noBufferToScreen)
+void Box::show()
 {
-  Log::getInstance()->log("Box", Log::DEBUG, "Show data %p %u %u %u %u %u", surface, screenX, screenY, width, height, noBufferToScreen);
-  surface->updateToBuffer(screenX, screenY, width, height);
-  if (!noBufferToScreen) Surface::bufferToScreen(screenX, screenY, width, height);
+  show(area);
+}
+
+void Box::show(Region& r)
+{
+  Log::getInstance()->log("Box", Log::DEBUG, "Show region %p %u %u %u %u", surface, r.x, r.y, r.w, r.h);
+//  surface->updateToScreen(area.x, area.y, area.w, area.h);
+
+  /* surface update to screen needs:
+  source x distance into this surface
+  source y distance into this surface
+  width of update
+  height of update
+  destination x on screen
+  destination y on screen
+  */
+
+  surface->updateToScreen(r.x - area.x, r.y - area.y, r.w, r.h, r.x, r.y);
 }
 
 int Box::getScreenX()
 {
-  return screenX;
+  return area.x;
 }
 
 int Box::getScreenY()
 {
-  return screenY;
+  return area.y;
 }
 
 int Box::getWidth()
 {
-  return width;
+  return area.w;
 }
 
 int Box::getHeight()
 {
-  return height;
+  return area.h;
 }
 
 // Level 1 drawing functions
 
 void Box::fillColour(Colour& colour)
 {
-  rectangle(0, 0, width, height, colour);
+  rectangle(0, 0, area.w, area.h, colour);
 }
 
 void Box::drawPara(char* text, int x, int y, Colour& colour)
@@ -127,7 +142,7 @@ void Box::drawPara(char* text, int x, int y, Colour& colour)
       }
 
       thisCharWidth = surface->getCharWidth(text[textPos]);
-      if ((lineWidth + thisCharWidth) > (int)(width - (2 * paraMargin)))
+      if ((lineWidth + thisCharWidth) > (int)(area.w - (2 * paraMargin)))
       {
         // this character would break the right margin
         if (text[textPos] == ' ')
@@ -159,7 +174,7 @@ void Box::drawPara(char* text, int x, int y, Colour& colour)
     {
       drawText(line, x, ypos, colour);
       ypos += lineHeight;
-      if (ypos > (int)(height - lineHeight)) break;
+      if (ypos > (int)(area.h - lineHeight)) break;
     }
     else
     {
diff --git a/box.h b/box.h
index 8f48056b6e693181969d7039b7df0bce4afb300c..cbefd6090c9bd09bfcf6dbe3f21bb9f87ed75571 100644 (file)
--- a/box.h
+++ b/box.h
@@ -26,6 +26,7 @@
 #include "log.h"
 #include "colour.h"
 #include "surface.h"
+#include "region.h"
 
 // Abstract ???????
 class Box
@@ -37,7 +38,8 @@ class Box
     void setScreenPos(int x, int y);
     void setSurfaceOffset(UINT x, UINT y);
 
-    void show(int noBufferToScreen = 0);
+    void show();
+    void show(Region& r);
 
     virtual void draw();
 
@@ -56,15 +58,21 @@ class Box
     int getWidth();
     int getHeight();
 
+    // so viewman can read it:
+    Region area;
+    Surface* surface; // temp  - is there a get function for this? FIXME
   private:
 
   protected:
-    Surface* surface;
+
+
+/*
     UINT width;
     UINT height;
 
     int screenX;
     int screenY;
+*/
 
     UINT offsetX;
     UINT offsetY;
index d30729c136a7de2ed0b9acd56efe0364b2f9a629..ee9cf36f454c31755d59063c3644fdfb442ea407 100644 (file)
@@ -253,7 +253,7 @@ void Command::doJustConnected(VConnect* vconnect)
 {
   I18n::Initialize();
   Video* video = Video::getInstance();
-  viewman->removeView(vconnect, 0, 1);
+  viewman->removeView(vconnect, 0);
 
   VInfo* vi = new VInfo();
   vi->create(400, 200);
diff --git a/main.cc b/main.cc
index 333d63fe2a2bc1d32084e514427615172ab44ceb..a4e1bfe969ce24aa87341b5f3d25c88b7d305ee6 100644 (file)
--- a/main.cc
+++ b/main.cc
@@ -206,7 +206,7 @@ int main(int argc, char** argv)
     shutdown(1);
   }
 
-  success = osd->init("/dev/stbgfx", 1);
+  success = osd->init("/dev/stbgfx");
   if (success)
   {
     logger->log("Core", Log::INFO, "OSD module initialised");
index fafb3c4d72fa6efc01445074eed5ef989e6b6f8c..2624faae8d4d899a42419b1239636694d913fc3e 100644 (file)
--- a/message.h
+++ b/message.h
@@ -41,20 +41,19 @@ class Message
     const static ULONG CLOSE_ME = 2;
     const static ULONG PLAY_SELECTED_RECORDING = 3;
     const static ULONG DELETE_SELECTED_RECORDING = 4;
-    const static ULONG UPDATE_SCREEN = 5;
-    const static ULONG SWAP_ME_FOR = 6;
-    const static ULONG CHANNEL_CHANGE = 7;
-    const static ULONG RESUME_SELECTED_RECORDING = 8;
-    const static ULONG STANDBY = 9;
-    const static ULONG STOP_PLAYBACK = 10;
-    const static ULONG SERVER_SELECTED = 11;
-    const static ULONG VDR_CONNECTED = 12;
-    const static ULONG REDRAW_DATA = 13;
-    const static ULONG ADD_VIEW = 14;
-    const static ULONG CHANNEL_UP = 15;
-    const static ULONG CHANNEL_DOWN = 16;
-    const static ULONG STREAM_END = 17;
-    const static ULONG CHILD_CLOSE = 18;
+    const static ULONG SWAP_ME_FOR = 5;
+    const static ULONG CHANNEL_CHANGE = 6;
+    const static ULONG RESUME_SELECTED_RECORDING = 7;
+    const static ULONG STANDBY = 8;
+    const static ULONG STOP_PLAYBACK = 9;
+    const static ULONG SERVER_SELECTED = 10;
+    const static ULONG VDR_CONNECTED = 11;
+    const static ULONG REDRAW_DATA = 12;
+    const static ULONG ADD_VIEW = 13;
+    const static ULONG CHANNEL_UP = 14;
+    const static ULONG CHANNEL_DOWN = 15;
+    const static ULONG STREAM_END = 16;
+    const static ULONG CHILD_CLOSE = 17;
 };
 
 #endif
diff --git a/osd.cc b/osd.cc
index 71190f0b6d556c9b08e93209c3fdb76cdc9f191e..751b85850edc96751d8cbe05216eb4cd629a3c65 100644 (file)
--- a/osd.cc
+++ b/osd.cc
@@ -30,7 +30,6 @@ Osd::Osd()
 
   fdOsd = 0;
   screen = NULL;
-  buffer = NULL;
 }
 
 Osd::~Osd()
@@ -50,7 +49,7 @@ int Osd::getFD()
   return fdOsd;
 }
 
-int Osd::init(char* device, int doubleBuffering)
+int Osd::init(char* device)
 {
   if (initted) return 0;
 
@@ -71,16 +70,6 @@ int Osd::init(char* device, int doubleBuffering)
   screen->create(video->getScreenWidth(), video->getScreenHeight());
   screen->display();
 
-  if (doubleBuffering)
-  {
-    buffer = new Surface(Surface::BUFFER);
-    buffer->create(video->getScreenWidth(), video->getScreenHeight());
-  }
-  else
-  {
-    Surface::disableBuffer();
-  }
-
   return 1;
 }
 
@@ -88,7 +77,6 @@ int Osd::shutdown()
 {
   if (!initted) return 0;
   initted = 0;
-  if (buffer) delete buffer;
   delete screen;
   close(fdOsd);
   return 1;
diff --git a/osd.h b/osd.h
index aae86051ee45c65b2f2e3e89af70665112efffac..cc258ed022f95e83fd61e0c48ff07191ab09e1e4 100644 (file)
--- a/osd.h
+++ b/osd.h
@@ -37,7 +37,7 @@ class Osd
     ~Osd();
     static Osd* getInstance();
 
-    int init(char* device, int doubleBuffering);
+    int init(char* device);
     int shutdown();
 
     int getFD();
@@ -47,10 +47,7 @@ class Osd
   private:
     static Osd* instance;
     int initted;
-
     Surface* screen;
-    Surface* buffer;
-
     int fdOsd;
 };
 
diff --git a/region.cc b/region.cc
new file mode 100644 (file)
index 0000000..f92326f
--- /dev/null
+++ b/region.cc
@@ -0,0 +1,88 @@
+#include "region.h"
+
+Region::Region()
+{
+  x = 0;
+  y = 0;
+  w = 0;
+  h = 0;
+  z = 0;
+}
+
+bool Region::overlappedBy(Region& d)
+{
+  return
+  ( (d.x2() >= x) &&
+    (d.x <= x2()) &&
+    (d.y <= y2()) &&
+    (d.y2() >= y)    );
+}
+
+UINT Region::x2()
+{
+  return x + w - 1;
+}
+
+UINT Region::y2()
+{
+  return y + h - 1;
+}
+/*
+Region Region::subtract(Region& other)
+{
+  printf("This:           %i %i %i %i\n", x, y, w, h);
+  printf("Subtract this:  %i %i %i %i\n", other.x, other.y, other.w, other.h);
+
+
+  Region s;
+
+  if (x < other.x)
+  {
+    printf("Case 1\n");
+    s.x = x;
+    s.y = y;
+    s.w = other.x - x;
+    s.h = h;
+  }
+  else if (x2() > other.x2())
+  {
+    printf("Case 2\n");
+    s.x = other.x2()+1;
+    s.y = y;
+    s.w = w - s.x;
+    s.h = h;
+  }
+  else if (y < other.y)
+  {
+    printf("Case 3\n");
+    s.x = x;
+    s.y = y;
+    s.w = w;
+    s.h = other.y - y;
+  }
+  else if (y2() > other.y2())
+  {
+    printf("Case 4\n");
+    s.x = x;
+    s.y = other.y2()+1;
+    s.w = w;
+    s.h = h - s.y;
+  }
+  else
+  {
+    s.x = 0;
+    s.y = 0;
+    s.w = 0;
+    s.h = 0;
+  }
+  printf("Result:         %i %i %i %i\n", s.x, s.y, s.w, s.h);
+
+  return s;
+}
+*/
+
+  //i.x = (x >= other.x ? x : other.x);
+  //i.y = (y >= other.y ? y : other.y);
+  //i.w = (x2() <= other.x2() ? x2() : other.x2()) - i.x;
+  //i.h = (y2() <= other.y2() ? y2() : other.y2()) - i.y;
+  //return i;
diff --git a/region.h b/region.h
new file mode 100644 (file)
index 0000000..3d98406
--- /dev/null
+++ b/region.h
@@ -0,0 +1,23 @@
+#ifndef REGION_H
+#define REGION_H
+
+#include <stdio.h>
+#include "defines.h"
+
+class Region
+{
+  public:
+    Region();
+    bool overlappedBy(Region& doesthisOverlap);
+//    Region subtract(Region& other);
+    UINT x2();
+    UINT y2();
+
+    UINT x;
+    UINT y;
+    UINT w;
+    UINT h;
+    int z;
+};
+
+#endif
index 13af55e53bfe62a2f8f327a2f70994706183420e..9f6c54e70671a48a99727818132b60a4c6136fc7 100644 (file)
 #include "osd.h"
 
 Surface* Surface::screen = NULL;
-Surface* Surface::buffer = NULL;
-int Surface::disableDoubleBuffering = 0;
 osd_font_t* Surface::font = &font_helvB18;
 
 Surface::Surface(int id)
 {
   if (id == SCREEN) screen = this;
-  if (id == BUFFER) buffer = this;
 
   fdOsd = Osd::getInstance()->getFD();
   memset(&surface, 0, sizeof(osd_surface_t));
@@ -55,17 +52,9 @@ Surface::~Surface()
 
 }
 
-void Surface::disableBuffer()
+Surface* Surface::getScreen()
 {
-  disableDoubleBuffering = 1;
-}
-
-Surface* Surface::getObject(int id)
-{
-  if (id == SCREEN) return screen;
-  if (disableDoubleBuffering) return screen;
-  if (id == BUFFER) return buffer;
-  return NULL;
+  return screen;
 }
 
 int Surface::create(UINT width, UINT height)
@@ -282,36 +271,18 @@ void Surface::drawVertLine(int x, int y1, int y2, unsigned int c)
   fillblt(x, y1, 1, y2-y1, c);
 }
 
-void Surface::bufferToScreen() // static, this is for Box::showAll
-{
-  if (disableDoubleBuffering) return;
-
-  Log::getInstance()->log("Surface", Log::DEBUG, "Full buffer to screen");
-  bufferToScreen(0, 0, buffer->surface.sfc.width, buffer->surface.sfc.height);
-}
 
-//int Surface::updateToScreen(int x, int y, int width, int height) // main method for all normal windows
-//{
-  /*
-  With double buffering:
-    A view has buffer for its surface. this is buffer, copy area specified to screen
-  Without double buffering:
-    A view has screen for its surface. this is screen, all painting work has already been done. ignore
+  /* surface update to screen needs:
+  source x distance into this surface
+  source y distance into this surface
+  width of update
+  height of update
+  destination x on screen
+  destination y on screen
   */
-
-//  if (this == screen) return 0;
-//
-//  return blt(fdOsd, surface.sfc.handle, x, y, width, height, screen->getSurfaceHandle(), x, y);
-//}
-
-int Surface::bufferToScreen(int x, int y, int width, int height) // static
-{
-  return blt(Osd::getInstance()->getFD(), buffer->getSurfaceHandle(), x, y, width, height, screen->getSurfaceHandle(), x, y);
-}
-
-int Surface::updateToBuffer(int x, int y, int width, int height) // main method for all normal windows
+int Surface::updateToScreen(int sx, int sy, int w, int h, int dx, int dy) // FIXME new, replace others with this FIXME
 {
-  return blt(fdOsd, surface.sfc.handle, 0, 0, width, height, buffer->getSurfaceHandle(), x, y);
+  return blt(fdOsd, surface.sfc.handle, sx, sy, w, h, screen->getSurfaceHandle(), dx, dy);
 }
 
 int Surface::blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy)
index 1b5dfa43ecccfd5881fb8f2e9843e2c76ec4c5b8..ac11deb22b034e06c9d560b97dc7a073b59cfc6d 100644 (file)
--- a/surface.h
+++ b/surface.h
@@ -170,8 +170,7 @@ class Surface
     Surface(int id = 0);
     ~Surface();
 
-    static Surface* getObject(int id);
-    static int bufferToScreen(int x, int y, int width, int height);
+    static Surface* getScreen();
     static int getFontHeight();
 
     int create(UINT width, UINT height);
@@ -182,7 +181,8 @@ class Surface
     void drawPixel(int x, int y, unsigned int c);
     void drawHorzLine(int x1, int x2, int y, unsigned int c);
     void drawVertLine(int x, int y1, int y2, unsigned int c);
-    int updateToBuffer(int x, int y, int width, int height);
+    int updateToScreen(int sx, int sy, int w, int h, int dx, int dy);
+
     int drawText(char* text, int x, int y, int r, int g, int b);
     int drawTextRJ(char* text, int x, int y, int r, int g, int b);
     int getCharWidth(char c);
@@ -192,8 +192,6 @@ class Surface
 
     static void initConversionTables();
 
-    static void disableBuffer();
-    static void bufferToScreen();
     static int blt(int fd, unsigned long shandle, int sx, int sy, int width, int height, unsigned long dhandle, int dx, int dy);
 
     const static int SCREEN = 1;
@@ -216,8 +214,6 @@ class Surface
 
   private:
     static Surface* screen;
-    static Surface* buffer;
-    static int disableDoubleBuffering;
     static osd_font_t* font;
 
     int fdOsd;
index 50f03122be8ef7c892533b6882884cfc937bc129..82d0e05c96e236956dbf1c6fc9bead7754854ed9 100644 (file)
@@ -48,7 +48,7 @@ VChannelList::VChannelList(ULONG type)
 
   sl.setSurface(surface);
   sl.setSurfaceOffset(10, 30 + 5);
-  sl.setDimensions(width - 20, height - 30 - 15 - 30);
+  sl.setDimensions(area.w - 20, area.h - 30 - 15 - 30);
 }
 
 VChannelList::~VChannelList()
diff --git a/view.cc b/view.cc
index 33c54206768429e66c55135d9d79dacc31ffc275..c0e348d6e92c9ee9e8fc63ec2b23f4486f6e4faf 100644 (file)
--- a/view.cc
+++ b/view.cc
@@ -24,11 +24,6 @@ char View::numViews = 0;
 
 View::View()
 {
-  width = 0;
-  height = 0;
-  screenX = 0;
-  screenY = 0;
-
   delSec = 0;
   delNSec = 0;
   seconds = 0;
@@ -56,11 +51,11 @@ View::~View()
 
 bool View::create(UINT w, UINT h)
 {
-  width = w;
-  height = h;
+  area.w = w;
+  area.h = h;
 
   surface = new Surface();
-  return surface->create(width, height);
+  return surface->create(area.w, area.h);
 }
 
 void View::setTitleText(char* takeText)
@@ -75,8 +70,8 @@ void View::draw()
 
   if (borderOn)
   {
-    rectangle(0, 0, width, height, titleBarColour);
-    rectangle(5, 5, width-10, height-10, backgroundColour);
+    rectangle(0, 0, area.w, area.h, titleBarColour);
+    rectangle(5, 5, area.w-10, area.h-10, backgroundColour);
   }
   else
   {
@@ -85,7 +80,7 @@ void View::draw()
 
   if (titleBarOn)
   {
-    rectangle(0, 0, width, 30, titleBarColour);
+    rectangle(0, 0, area.w, 30, titleBarColour);
     if (titleText) drawText(titleText, 5, 5, Colour::LIGHTTEXT);
   }
 }
index 8840d86d0d29c98b2a407723453f042b130d8e65..6619f5b1c65b6a838f2d996f9ce16945707a565c 100644 (file)
@@ -27,7 +27,7 @@ ViewMan::ViewMan()
   if (instance) return;
   instance = this;
   initted = 0;
-  topView = 0;
+  numViews = 0;
   resetThreadFlag = 0;
   autoDeleteThreadRun = 0;
   callFromThread = 0;
@@ -73,12 +73,11 @@ int ViewMan::shutdown()
 int ViewMan::add(View* v)
 {
   if (!initted) return 0;
-  if (topView == 10) return 0;
+  if (numViews == 20) return 0;
 
   pthread_mutex_lock(&viewManLock);
 
-  topView++;
-  views[topView] = v;
+  views[numViews++] = v;
 
   resetThread();
   pthread_mutex_unlock(&viewManLock);
@@ -89,10 +88,9 @@ int ViewMan::add(View* v)
 int ViewMan::addNoLock(View* v)
 {
   if (!initted) return 0;
-  if (topView == 10) return 0;
+  if (numViews == 20) return 0;
 
-  topView++;
-  views[topView] = v;
+  views[numViews++] = v;
 
   resetThread();
 
@@ -102,40 +100,32 @@ int ViewMan::addNoLock(View* v)
 
 // ---------------------------------------------------- REMOVE CODE
 
-int ViewMan::removeView(View* toDelete, int noLock, int noShow)
+int ViewMan::removeView(View* toDelete, int noLock)
 {
   if (!initted) return 0;
-  if (topView == 0) return 0;
+  if (numViews == 0) return 0;
 
   if (!noLock) pthread_mutex_lock(&viewManLock);
 
-  Log::getInstance()->log("ViewMan", Log::DEBUG, "entering remove, %u topview", topView);
+  Log::getInstance()->log("ViewMan", Log::DEBUG, "entering remove, numViews=%i", numViews);
 
   int i;
-  int wasTopView = 0;
-  int slotTakenFrom = 0;
 
   if (toDelete == NULL)
   {
-    toDelete = views[topView];
-    i = topView;
-    wasTopView = 1;
+    toDelete = views[numViews-1];
+    i = numViews - 1;
   }
   else
   {
     // to be deleted view is more likely to be at the top
-
-
-    for (i = topView; i > 0; i--)
+    for (i = numViews-1; i >= 0; i--)
     {
-      if (views[i] == toDelete)
-      {
-        if (i == topView) wasTopView = 1;
-        break;
-      }
+      Log::getInstance()->log("ViewMan", Log::DEBUG, "todel: %p, i=%i, views[i]=%p", toDelete, i, views[i]);
+      if (views[i] == toDelete) break;
     }
 
-    if (i == 0)
+    if (i == -1)
     {
       // not a View we have!
       if (!noLock) pthread_mutex_unlock(&viewManLock);
@@ -143,117 +133,227 @@ int ViewMan::removeView(View* toDelete, int noLock, int noShow)
     }
   }
 
-  // Save the position we are deleting the view from
-  slotTakenFrom = i;
+  Log::getInstance()->log("ViewMan", Log::DEBUG, "Starting deleteView");
+  deleteView(i);
+  Log::getInstance()->log("ViewMan", Log::DEBUG, "Done deleteView");
 
   // Shift the views on top down one
-  for(; i < topView; i++)
-  {
-    views[i] = views[i + 1];
-  }
-  topView--;
+  --numViews;
+  for(int j = i; j < numViews; j++) views[j] = views[j+1];
 
-  // Done. Now on to drawing.
+  // Delete the view
+  delete toDelete;
 
-  View* newTopBox = views[topView]; // just to make second optimisation easier
+  resetThread();
+  if (!noLock) pthread_mutex_unlock(&viewManLock);
+
+  return 1;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// NEW STUFF
+/////////////////////////////////////////////////////////////////////////////
 
-  // First optimisation. If there are no views left, don't do anything!
-  if (topView == 0)
+void ViewMan::deleteView(int z)
+{
+  Log::getInstance()->log("ViewMan", Log::DEBUG, "Delete view %i of %i", z, numViews);
+  RegionList rl;
+  boxSplit(views[z]->area, z + 1, numViews, 1, rl);
+  while(!rl.empty())
   {
-    Log::getInstance()->log("ViewMan", Log::DEBUG, "re-draw using optimisation 1");
+    repaintRevealed(z, rl.front());
+    rl.pop_front();
   }
+}
+
+/* For later...
+void ViewMan::update(int z)
+{
+  // get the region for the whole view, could be less than that
+  // for smaller updates
 
-  // second optimisation. if view being deleted is entirely within the view underneath it,
-  // and was the top most box,
-  // only need to redraw the one underneath
-  else if (   wasTopView
-           && (toDelete->getScreenX() >= newTopBox->getScreenX())
-           && (toDelete->getScreenY() >= newTopBox->getScreenY())
-           && ((toDelete->getScreenX() + toDelete->getWidth()) <= (newTopBox->getScreenX() + newTopBox->getWidth()))
-           && ((toDelete->getScreenY() + toDelete->getHeight()) <= (newTopBox->getScreenY() + newTopBox->getHeight()))
-          )
+  Region r = views[z]->area;
+  RegionList rl;
+
+  r.y += 10;
+
+  Region r2;
+  boxSplit(r, z+1, numViews, 1, rl);
+  while(!rl.empty())
   {
-    newTopBox->show();
-    Log::getInstance()->log("ViewMan", Log::DEBUG, "re-draw using optimisation 2");
+    r2 = rl.front();
+    r2.z = z;
+    views[z]->show(r2);
+    rl.pop_front();
   }
+}
+*/
+
+void ViewMan::repaintRevealed(int x, Region r)
+{
+  RegionList rl;
+  boxSplit(r, x - 1, -1, -1, rl);
 
-  // third optimisation. if the box being deleted is totally within one above it, don't do anything
-  else if ((slotTakenFrom <= topView) && isTotallyCovered(toDelete, slotTakenFrom))
+  Region r2;
+  while(!rl.empty())
   {
-    Log::getInstance()->log("ViewMan", Log::DEBUG, "re-draw using optimisation 3");
+    r2 = rl.front();
+    views[r2.z]->show(r2);
+    rl.pop_front();
   }
+}
 
-  // no optimisations left, redo everything.
-  else
+void ViewMan::boxSplit(Region r, int start, int end, int direction, RegionList& rl)
+{
+//  printf("Y=  S=%i E=%i D=%i: Boxsplit: %i %i %i %i\n", start, end, direction, r.x, r.y, r.w, r.h);
+
+  for(int z = start; z != end; z += direction)
   {
-    for (int j = 1; j <= topView; j++)
+    if (r.overlappedBy(views[z]->area))
     {
-      views[j]->show(1);
-    }
-    if (!noShow) Surface::bufferToScreen();
+//      printf("Z=%i S=%i E=%i D=%i: %i overlaps\n", z, start, end, direction, z);
 
-    Log::getInstance()->log("ViewMan", Log::DEBUG, "re-draw using no optimisation");
-  }
+      int top = r.y;
+      int btm = r.y2();
 
-  // Delete the view
-  delete toDelete;
+      if (views[z]->area.y > r.y)
+      {
+//        printf("Z=%i S=%i E=%i D=%i: Case 1 for %i %i %i %i split by %i: %i %i %i %i\n", z, start, end, direction, r.x, r.y, r.w, r.h, z, views[z]->area.x, views[z]->area.y, views[z]->area.w, views[z]->area.h);
+        top = views[z]->area.y;
+        Region newR;
+        newR.x = r.x;
+        newR.y = r.y;
+        newR.w = r.w;
+        newR.h = views[z]->area.y - r.y;
+        boxSplit(newR, z + direction, end, direction, rl);
+
+        if (direction == -1)
+        {
+          Region newR2;
+          newR2.x = r.x;
+          newR2.y = views[z]->area.y;
+          newR2.w = r.w;
+          newR2.h = r.h - newR.h;
+          boxSplit(newR2, z, end, -1, rl);
+          return;
+        }
+      }
 
-  resetThread();
-  if (!noLock) pthread_mutex_unlock(&viewManLock);
+      if (views[z]->area.y2() < r.y2())
+      {
+//        printf("Z=%i S=%i E=%i D=%i: Case 2 for %i %i %i %i split by %i: %i %i %i %i\n", z, start, end, direction, r.x, r.y, r.w, r.h, z, views[z]->area.x, views[z]->area.y, views[z]->area.w, views[z]->area.h);
+        btm = views[z]->area.y2();
+        Region newR;
+        newR.x = r.x;
+        newR.y = views[z]->area.y2() + 1;
+        newR.w = r.w;
+        newR.h = r.y2() - newR.y + 1;
+        boxSplit(newR, z + direction, end, direction, rl);
+
+        if (direction == -1)
+        {
+          Region newR2;
+          newR2.x = r.x;
+          newR2.y = r.y;
+          newR2.w = r.w;
+          newR2.h = r.h - newR.h;
+          boxSplit(newR2, z, end, -1, rl);
+          return;
+        }
+      }
 
-  return 1;
-}
+      if (views[z]->area.x > r.x)
+      {
+//        printf("Z=%i S=%i E=%i D=%i: Case 3 for %i %i %i %i split by %i: %i %i %i %i\n", z, start, end, direction, r.x, r.y, r.w, r.h, z, views[z]->area.x, views[z]->area.y, views[z]->area.w, views[z]->area.h);
+        Region newR;
+        newR.x = r.x;
+        newR.y = top;
+        newR.w = views[z]->area.x - r.x;
+        newR.h = btm - top + 1;
+        boxSplit(newR, z + direction, end, direction, rl);
+
+        if (direction == -1)
+        {
+          Region newR2;
+          newR2.x = r.x + newR.w;
+          newR2.y = r.y;
+          newR2.w = r.w - newR.w;
+          newR2.h = r.h;
+          boxSplit(newR2, z, end, -1, rl);
+          return;
+        }
+      }
 
-int ViewMan::isTotallyCovered(View* toDelete, int slotTakenFrom)
-{
-  int todelx1 = toDelete->getScreenX();
-  int todelx2 = toDelete->getScreenX() + toDelete->getWidth();
-  int todely1 = toDelete->getScreenY();
-  int todely2 = toDelete->getScreenY() + toDelete->getHeight();
-
-  int x1 = 999999;
-  int x2 = 0;
-  int y1 = 999999;
-  int y2 = 0;
-
-  int currentx1;
-  int currentx2;
-  int currenty1;
-  int currenty2;
-
-  for (int i = slotTakenFrom; i <= topView; i++)
-  {
-    currentx1 = views[i]->getScreenX();
-    currentx2 = currentx1 + views[i]->getWidth();
-    currenty1 = views[i]->getScreenY();
-    currenty2 = currenty1 + views[i]->getHeight();
+      if (views[z]->area.x2() < r.x2())
+      {
+//        printf("Z=%i S=%i E=%i D=%i: Case 4 for %i %i %i %i split by %i: %i %i %i %i\n", z, start, end, direction, r.x, r.y, r.w, r.h, z, views[z]->area.x, views[z]->area.y, views[z]->area.w, views[z]->area.h);
+        Region newR;
+        newR.x = views[z]->area.x2() + 1;
+        newR.y = top;
+        newR.w = r.x2() - newR.x + 1;
+        newR.h = btm - top + 1;
+        boxSplit(newR, z + direction, end, direction, rl);
+
+        if (direction == -1)
+        {
+          Region newR2;
+          newR2.x = r.x;
+          newR2.y = r.y;
+          newR2.w = r.w - newR.w;
+          newR2.h = r.h;
+          boxSplit(newR2, z, end, -1, rl);
+          return;
+        }
+      }
 
-//    printf("Iteration in tc before. i=%i x1=%i x2=%i y1=%i y2=%i cx1=%i cx2=%i cy1=%i cy2=%i\n", i, x1, x2, y1, y2, currentx1, currentx2, currenty1, currenty2);
+      if (direction == -1)
+      {
+        // we are going down the stack
+        // r is underlapped by views[z]
+        // but we have not split
+        // Therefore this region under test is
+        // completely covering views[z]
 
-    if (currentx1 < x1) x1 = currentx1;
-    if (currentx2 > x2) x2 = currentx2;
-    if (currenty1 < y1) y1 = currenty1;
-    if (currenty2 > y2) y2 = currenty2;
+        // don't go any further down, generate a region and quit
 
-//    printf("Iteration in tc after . i=%i x1=%i x2=%i y1=%i y2=%i\n", i, x1, x2, y1, y2);
+//        printf("Repaint region: %i %i %i %i\n", r.x, r.y, r.w, r.h);
+        r.z = z;
+        rl.push_front(r);
+      }
+
+//      printf("Returning from Z=%i\n", z);
+      return;
+    }
+    else
+    {
+//      printf("Z=%i S=%i E=%i D=%i: %i does not overlap\n", z, start, end, direction, z);
+    }
   }
 
-  // k, now x1 x2 y1 y2 contain the dimensions of the biggest box over the deleted slot
+  // if direction = 1 then we have come to a region that is
+  // entirely clear of higher views and needs to be redrawn
 
-  if (   (x1 <= todelx1)
-      && (x2 >= todelx2)
-      && (y1 <= todely1)
-      && (y2 >= todely2)
-     )
-  {
-    return 1;
-  }
-  else
+  // if direction = -1 then we have come to a region that is on
+  // the very bottom with nothing below it to repaint.
+  // do nothing. stale window data will be left on screen?
+
+  if (direction == 1)
   {
-    return 0;
+    rl.push_front(r);
   }
 }
 
+// TEMP
+void ViewMan::drawBlack(Region& r)
+{
+  Surface* surface = Surface::getScreen();
+  surface->fillblt(r.x, r.y, r.w, r.h, surface->rgba(0, 0, 0, 255));
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// END NEW STUFF
+/////////////////////////////////////////////////////////////////////////////
+
 // ---------------------------------------------------- END OF REMOVE CODE
 
 
@@ -261,14 +361,13 @@ void ViewMan::removeAll()
 {
   pthread_mutex_lock(&viewManLock);
 
-  // FIXME for don't delete wallpaper cos surface destroy doesn't work
-
-  for (; topView > 1; topView--)
+  // 1.. Don't delete wallpaper. No point.
+  for (; numViews > 1; --numViews)
   {
-    delete views[topView];
+    delete views[numViews-1];
   }
 
-  Surface::bufferToScreen();
+//  Surface::bufferToScreen();
 
   resetThread();
   pthread_mutex_unlock(&viewManLock);
@@ -284,15 +383,15 @@ int ViewMan::handleCommand(UCHAR command)
 
   if (command != Remote::NA_NONE)
   {
-
     // handle command return values
     // 0 - drop through to next view
     // 1 - dont drop to next view, but not handled
     // 2 - handled - stop command here
     // 4 - handled - delete this view
 
-    for (i=topView; i>0; i--)
+    for (i=numViews-1; i>=0; i--)
     {
+      Log::getInstance()->log("ViewMan", Log::DEBUG, "Giving command to i=%i", i);
       retVal = views[i]->handleCommand(command);
       if (retVal == 1)
       {
@@ -321,6 +420,7 @@ int ViewMan::handleCommand(UCHAR command)
   //      removeNoLock(views[i]);
   //      Box::showAll();
   //      resetThread();
+        Log::getInstance()->log("ViewMan", Log::DEBUG, "Return 4: i=%i, views[i]=%p", i, views[i]);
         removeView(views[i], 1);
         pthread_mutex_unlock(&viewManLock);
         retVal2 = 1;
@@ -346,7 +446,7 @@ void ViewMan::processMessage(Message* m)
 {
   if (m->to != this)
   {
-    for (int i = topView; i > 0; i--)
+    for (int i = numViews-1; i >= 0; i--)
     {
       if (views[i] == m->to)
       {
@@ -364,22 +464,17 @@ void ViewMan::processMessage(Message* m)
   {
     case Message::CLOSE_ME:
     {
-      removeView((View*)m->from, 1, 1);
-      break;
-    }
-    case Message::UPDATE_SCREEN:
-    {
-      Surface::bufferToScreen();
+      removeView((View*)m->from, 1);
       break;
     }
     case Message::SWAP_ME_FOR:
     {
       View* toReplace = (View*) m->parameter;
 
-      removeView((View*)m->from, 1, 1);
+      removeView((View*)m->from, 1);
 
-      topView++;
-      views[topView] = toReplace;
+      views[numViews] = toReplace;
+      ++numViews;
       if (toReplace->seconds)
       {
         struct timespec currentTime;
@@ -389,7 +484,6 @@ void ViewMan::processMessage(Message* m)
       }
       toReplace->draw();
       toReplace->show();
-      Surface::bufferToScreen();
       resetThread();
       break;
     }
@@ -489,7 +583,7 @@ void ViewMan::startAutoDeleteThread3()
       nextTime.tv_nsec = 0;
       nextToDelete = NULL;
 
-      for(int i = 1; i <= topView; i++)
+      for(int i = 0; i < numViews; i++)
       {
         if ((views[i]->delSec > 0) && (views[i]->delNSec > 0))
         {
index 40da7401b1a13d724074626c7755ad457f3b7d40..83994457ea07eff8afb47068d1348f70578797f4 100644 (file)
--- a/viewman.h
+++ b/viewman.h
@@ -25,6 +25,7 @@
 #include <time.h>
 #include <signal.h>
 #include <pthread.h>
+#include <slist>
 
 #include "defines.h"
 #include "view.h"
@@ -32,6 +33,9 @@
 #include "messagequeue.h"
 #include "remote.h"
 #include "surface.h"
+#include "region.h"
+
+typedef slist<Region> RegionList;
 
 class ViewMan : public MessageQueue
 {
@@ -46,7 +50,7 @@ class ViewMan : public MessageQueue
     // All these reset the thread
     int add(View* v);
     int addNoLock(View* v);
-    int removeView(View* toRemove = NULL, int noLock = 0, int noShow = 0);
+    int removeView(View* toRemove = NULL, int noLock = 0);
     void removeAll();
 
     int handleCommand(UCHAR command);
@@ -56,13 +60,11 @@ class ViewMan : public MessageQueue
     void startAutoDeleteThread3();
 
   private:
-    int isTotallyCovered(View* toDelete, int slotTakenFrom);
-
     static ViewMan* instance;
     int initted;
 
-    View* views[11];
-    UCHAR topView;
+    View* views[20];
+    int numViews;
 
     // Threading stuff
 
@@ -77,6 +79,11 @@ class ViewMan : public MessageQueue
 
     void processMessage(Message* m);
 
+    // New windowing stuff
+    void deleteView(int z);
+    void repaintRevealed(int x, Region r);
+    void boxSplit(Region r, int start, int end, int direction, RegionList& rl);
+    void drawBlack(Region& r);
 };
 
 #endif
index 639873088380905d06716806d1b5667a61c194f0..8c7cc9bcbff825823f242af842ece5d48058b7e6 100644 (file)
@@ -42,7 +42,7 @@ VLiveBanner::VLiveBanner(View* tparent, Channel* channel)
 
   sl.setSurface(surface);
   sl.setSurfaceOffset(0, 30);
-  sl.setDimensions(width, height - 60);
+  sl.setDimensions(area.w, area.h - 60);
   sl.setNoLoop();
 
   setChannel(channel);
@@ -115,10 +115,10 @@ void VLiveBanner::draw()
 {
   View::draw();
   sl.draw();
-  rectangle(0, height - 30, width, 30, titleBarColour);
+  rectangle(0, area.h - 30, area.w, 30, titleBarColour);
 
-  rectangle(7, height - 24, 18, 16, Colour::RED);
-  drawText(tr("info"), 32, height - 25, Colour::LIGHTTEXT);
+  rectangle(7, area.h - 24, 18, 16, Colour::RED);
+  drawText(tr("info"), 32, area.h - 25, Colour::LIGHTTEXT);
 }
 
 int VLiveBanner::handleCommand(int command)
index 5cce73c0908f78c0f0c649fabdc59f47a0cf3ab2..c0b5443cd3941aef300b964696072676ea0fed7c 100644 (file)
@@ -41,7 +41,7 @@ VRecordingList::VRecordingList(VRecordingList* tparent)
 
   sl.setSurface(surface);
   sl.setSurfaceOffset(10, 30 + 5);
-  sl.setDimensions(width - 20, height - 30 - 15 - 30);
+  sl.setDimensions(area.w - 20, area.h - 30 - 15 - 30);
 }
 
 VRecordingList::~VRecordingList()
@@ -284,14 +284,6 @@ void VRecordingList::doDeleteSelected()
   }
 
   show();
-
-/*
-  Message* m2 = new Message();
-  m2->from = this;
-  m2->to = ViewMan::getInstance();
-  m2->message = Message::UPDATE_SCREEN;
-  ViewMan::getInstance()->postMessage(m2);
-*/
 }
 
 int VRecordingList::doPlay()
index bbc3b3b5bb632a9908944ee1a96485b28222fa16..6f6460241e09457cb88ad44dc8a1c04c2425b614 100644 (file)
@@ -43,7 +43,7 @@ VRecordingMenu::VRecordingMenu()
 
   sl.setSurface(surface);
   sl.setSurfaceOffset(10, 30 + 5);
-  sl.setDimensions(width - 20, height - 30 - 15);
+  sl.setDimensions(area.w - 20, area.h - 30 - 15);
   sl.addOption(tr("Play"), 1);
   sl.addOption(tr("Resume"), 0);
   sl.addOption(tr("Summary"), 0);
index 687c4a4efa358265a742ae3aca3eb0b21136adb1..9ade764b9411d59d2a97395154cdbeb1b8ce59ff 100644 (file)
@@ -44,7 +44,7 @@ VServerSelect::VServerSelect(std::vector<char*>* serverIPs)
 
   sl.setSurface(surface);
   sl.setSurfaceOffset(10, 30 + 5);
-  sl.setDimensions(width - 20, height - 30 - 15);
+  sl.setDimensions(area.w - 20, area.h - 30 - 15);
 
   sl.addOption((*serverIPs)[0], 1);
   for(UINT k = 1; k < serverIPs->size(); k++)
index 1dc413a9ef812b858473509c1cda02773c535a7a..bb0c33a9a13c5d5fe4282857c553be428bbac3ee 100644 (file)
@@ -234,7 +234,7 @@ void VVideoLive::play(int noShowVLB)
 void VVideoLive::stop(int noRemoveVLB)
 {
   if (unavailable) return;
-  if (!noRemoveVLB) viewman->removeView(vlb, 1, 1); // if live banner is present, remove it. won't cause damage if its not present
+  if (!noRemoveVLB) viewman->removeView(vlb, 1); // if live banner is present, remove it. won't cause damage if its not present
 
   player->stop();
   vdr->stopStreaming();
index 29cc91c4e2d636d863d2bf5e5aa5b540e983c40f..313be107b73f38d16ac264bb98a8fcaec3665cb0 100644 (file)
@@ -242,7 +242,7 @@ void VWelcome::doRecordingsList()
   }
 
   Log::getInstance()->log("VWelcome", Log::DEBUG, "possible delay start");
-  viewman->removeView(viewWait, 1, 1);
+  viewman->removeView(viewWait, 1);
   Log::getInstance()->log("VWelcome", Log::DEBUG, "possible delay end");
 }
 
index 8317fa60441021eee43d0f65b4a980dbb9550f26..3e833fe80ed259770983e1c4ab4de45d34657d31 100644 (file)
--- a/widget.cc
+++ b/widget.cc
@@ -22,8 +22,6 @@
 
 Widget::Widget()
 {
-  width = 0;
-  height = 0;
 }
 
 Widget::~Widget()
@@ -37,6 +35,6 @@ void Widget::setSurface(Surface* tsurface)
 
 void Widget::setDimensions(int twidth, int theight)
 {
-  width = twidth;
-  height = theight;
+  area.w = twidth;
+  area.h = theight;
 }
index b803564355c68132aeb7484b6d8065b6e064faaa..fb64a6aacb255eb85886356203aa669d78f05b9d 100644 (file)
--- a/wjpeg.cc
+++ b/wjpeg.cc
@@ -54,11 +54,11 @@ void WJpeg::draw()
 
   // MAKE THE 2D ARRAY
 
-  unsigned char* buffer = (unsigned char*)malloc(width * height * 3);
-  logger->log("BJpeg", Log::DEBUG, "Buffer allocated at %p, width = %i height = %i", buffer, width, height);
+  unsigned char* buffer = (unsigned char*)malloc(area.w * area.h * 3);
+  logger->log("BJpeg", Log::DEBUG, "Buffer allocated at %p, width = %i height = %i", buffer, area.w, area.h);
 
-  unsigned char* bufferPointers[height];
-  for(UINT ps = 0; ps < height; ps++) bufferPointers[ps] = buffer + (ps * width * 3);
+  unsigned char* bufferPointers[area.h];
+  for(UINT ps = 0; ps < area.h; ps++) bufferPointers[ps] = buffer + (ps * area.w * 3);
 
   logger->log("BJpeg", Log::DEBUG, "done array check");
 
@@ -66,7 +66,7 @@ void WJpeg::draw()
   while (cinfo.output_scanline < cinfo.output_height)
   {
 //  logger->log("BJpeg", Log::DEBUG, "%i", rowsread);
-    rowsread += jpeg_read_scanlines(&cinfo, &bufferPointers[rowsread], height);
+    rowsread += jpeg_read_scanlines(&cinfo, &bufferPointers[rowsread], area.h);
   }
 
   logger->log("BJpeg", Log::DEBUG, "Done all jpeg_read");
@@ -76,17 +76,17 @@ void WJpeg::draw()
 
   fclose(infile);
 
-  logger->log("BJpeg", Log::DEBUG, "jpeg shutdown done, x, y %u %u", width, height);
+  logger->log("BJpeg", Log::DEBUG, "jpeg shutdown done, x, y %u %u", area.w, area.h);
 
   Colour c;
   UINT x, y, xoff;
   unsigned char* p;
 
-  for (y = 0; y < height; y++)
+  for (y = 0; y < area.h; y++)
   {
     p = bufferPointers[y];
 
-    for (x = 0; x < width; x++)
+    for (x = 0; x < area.w; x++)
     {
       xoff = x * 3;
 
index 85c50e7bac7da5c365e563e6b5863f6d0d1258e2..2cd7c9eb4e8dc499f9e4c1770f7f54fb5ef247b5 100644 (file)
@@ -80,7 +80,7 @@ void WSelectList::draw()
   int fontHeight = surface->getFontHeight();
   int ySeperation = fontHeight + 1;
 
-  numOptionsDisplayable = (height - 5) / ySeperation;
+  numOptionsDisplayable = (area.h - 5) / ySeperation;
 
   if (selectedOption == (topOption + numOptionsDisplayable)) topOption++;
   if (selectedOption == ((UINT)topOption - 1)) topOption--;
@@ -100,11 +100,11 @@ void WSelectList::draw()
   for (UINT i = topOption; i < (topOption + numOptionsDisplayable); i++)
   {
     if (i == options.size()) return;
-    if ((ypos + ySeperation) > height) break;
+    if ((ypos + ySeperation) > area.h) break;
 
     if (i == selectedOption)
     {
-      rectangle(0, ypos, width, fontHeight, Colour::SELECTHIGHLIGHT);
+      rectangle(0, ypos, area.w, fontHeight, Colour::SELECTHIGHLIGHT);
       drawOptionLine(options[i], 5, ypos, Colour::DARKTEXT);
     }
     else