diff options
Diffstat (limited to 'interface.c')
-rw-r--r-- | interface.c | 86 |
1 files changed, 79 insertions, 7 deletions
diff --git a/interface.c b/interface.c index 3e1232f0..c0554ca3 100644 --- a/interface.c +++ b/interface.c @@ -4,10 +4,11 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: interface.c 1.26 2000/10/29 12:53:55 kls Exp $ + * $Id: interface.c 1.27 2000/11/01 11:25:25 kls Exp $ */ #include "interface.h" +#include <ctype.h> #include <unistd.h> cInterface *Interface = NULL; @@ -16,6 +17,7 @@ cInterface::cInterface(int SVDRPport) { open = 0; cols[0] = 0; + width = height = 0; keyFromWait = kNone; rcIo = NULL; SVDRP = NULL; @@ -40,15 +42,17 @@ cInterface::~cInterface() void cInterface::Open(int NumCols, int NumLines) { if (!open++) - cDvbApi::PrimaryDvbApi->Open(NumCols, NumLines); + cDvbApi::PrimaryDvbApi->Open(width = NumCols, height = NumLines); } void cInterface::Close(void) { if (open == 1) Clear(); - if (!--open) + if (!--open) { cDvbApi::PrimaryDvbApi->Close(); + width = height = 0; + } } unsigned int cInterface::GetCh(bool Wait, bool *Repeat, bool *Release) @@ -120,6 +124,74 @@ void cInterface::SetCols(int *c) } } +char *cInterface::WrapText(const char *Text, int Width, int *Height) +{ + // Wraps the Text to make it fit into the area defined by the given Width + // (which is given in character cells). + // The actual number of lines resulting from this operation is returned in + // Height. + // The returned string is newly created on the heap and the caller + // is responsible for deleting it once it is no longer used. + // Wrapping is done by inserting the necessary number of newline + // characters into the string. + + int Lines = 1; + char *t = strdup(Text); + char *Blank = NULL; + char *Delim = NULL; + int w = 0; + + Width *= cDvbApi::PrimaryDvbApi->CellWidth(); + + while (*t && t[strlen(t) - 1] == '\n') + t[strlen(t) - 1] = 0; // skips trailing newlines + + for (char *p = t; *p; ) { + if (*p == '\n') { + Lines++; + w = 0; + Blank = Delim = NULL; + p++; + continue; + } + else if (isspace(*p)) + Blank = p; + int cw = cDvbApi::PrimaryDvbApi->Width(*p); + if (w + cw > Width) { + if (Blank) { + *Blank = '\n'; + p = Blank; + continue; + } + else { + // Here's the ugly part, where we don't have any whitespace to + // punch in a newline, so we need to make room for it: + if (Delim) + p = Delim + 1; // let's fall back to the most recent delimiter + char *s = new char[strlen(t) + 2]; // The additional '\n' plus the terminating '\0' + int l = p - t; + strncpy(s, t, l); + s[l] = '\n'; + strcpy(s + l + 1, p); + delete t; + t = s; + p = t + l; + continue; + } + } + else + w += cw; + if (strchr("-.,:;!?_", *p)) { + Delim = p; + Blank = NULL; + } + p++; + } + + *Height = Lines; + return t; +} + void cInterface::Write(int x, int y, const char *s, eDvbColor FgColor, eDvbColor BgColor) { if (open) @@ -154,7 +226,7 @@ void cInterface::WriteText(int x, int y, const char *s, eDvbColor FgColor, eDvbC void cInterface::Title(const char *s) { - int x = (MenuColumns - strlen(s)) / 2; + int x = (Width() - strlen(s)) / 2; if (x < 0) x = 0; ClearEol(0, 0, clrCyan); @@ -203,7 +275,7 @@ bool cInterface::Confirm(const char *s) void cInterface::HelpButton(int Index, const char *Text, eDvbColor FgColor, eDvbColor BgColor) { if (open && Text) { - const int w = MenuColumns / 4; + const int w = Width() / 4; int l = (w - strlen(Text)) / 2; if (l < 0) l = 0; @@ -460,7 +532,7 @@ eKeys cInterface::DisplayDescription(const cEventInfo *EventInfo) int cInterface::WriteParagraph(int Line, const char *Text) { - if (Line < MenuLines && Text) { + if (Line < Height() && Text) { Line++; char *s = strdup(Text); char *pStart = s, *pEnd; @@ -479,7 +551,7 @@ int cInterface::WriteParagraph(int Line, const char *Text) //XXX need to scroll if text is longer *pEnd = 0; Write(1, Line++, pStart, clrCyan); - if (Line >= MenuLines) + if (Line >= Height()) return Line; pStart = pEnd + 1; } |