ROOT logo
// @(#)root/gui:$Id: TGString.cxx 23115 2008-04-10 13:35:37Z rdm $
// Author: Fons Rademakers   05/01/98

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/
/**************************************************************************

    This source is based on Xclass95, a Win95-looking GUI toolkit.
    Copyright (C) 1996, 1997 David Barth, Ricky Ralston, Hector Peraza.

    Xclass95 is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

**************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TGString and TGHotString                                             //
//                                                                      //
// TGString wraps a TString and adds some graphics routines like        //
// drawing, size of string on screen depending on font, etc.            //
// TGHotString is a string with a "hot" character unerlined.            //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TGString.h"
#include "TVirtualX.h"
#include "ctype.h"


ClassImp(TGString)
ClassImp(TGHotString)

//______________________________________________________________________________
TGString::TGString(const TGString *s) : TString(s->Data())
{ 
   // cconstructor
}

//______________________________________________________________________________
void TGString::Draw(Drawable_t id, GContext_t gc, Int_t x, Int_t y)
{
   // Draw string.

   gVirtualX->DrawString(id, gc, x, y, Data(), Length());
}

//______________________________________________________________________________
void TGString::DrawWrapped(Drawable_t id, GContext_t gc,
                           Int_t x, Int_t y, UInt_t w, FontStruct_t font)
{
   // Draw a string in a column with width w. If string is longer than
   // w wrap it to next line.

   const char *p     = Data();
   const char *prev  = p;
   const char *chunk = p;
   int tw, th, len = Length();

   tw = gVirtualX->TextWidth(font, p, len);
   if (tw <= (int)w) {
      gVirtualX->DrawString(id, gc, x, y, p, len);
      return;
   }

   int max_ascent, max_descent;
   gVirtualX->GetFontProperties(font, max_ascent, max_descent);
   th = max_ascent + max_descent + 1;

   while(1) {
      p = strchr(p, ' ');
      if (p == 0) {
         if (chunk) gVirtualX->DrawString(id, gc, x, y, chunk, strlen(chunk));
         break;
      }
      tw = gVirtualX->TextWidth(font, chunk, p-chunk);
      if (tw > (int)w) {
         if (prev == chunk)
            prev = ++p;
         else
            p = prev;
         gVirtualX->DrawString(id, gc, x, y, chunk, prev-chunk-1);
         chunk = prev;
         y += th;
      } else {
         prev = ++p;
      }
   }
}

//______________________________________________________________________________
Int_t TGString::GetLines(FontStruct_t font, UInt_t w)
{
   // Get number of lines of width w the string would take using a certain font.

   const char *p     = Data();
   const char *prev  = p;
   const char *chunk = p;
   int tw, nlines, len = Length();

   nlines = 1;

   tw = gVirtualX->TextWidth(font, p, len);
   if (tw <= (int)w) return nlines;

   while(1) {
      p = strchr(p, ' ');
      if (p == 0) break;
      tw = gVirtualX->TextWidth(font, chunk, p-chunk);
      if (tw > (int)w) {
         if (prev == chunk)
            chunk = prev = ++p;
         else
            p = chunk = prev;
         ++nlines;
      } else {
         prev = ++p;
      }
   }
   return nlines;
}


//______________________________________________________________________________
TGHotString::TGHotString(const char *s) : TGString()
{
   // Create a hot string.

   fLastGC = 0;
   fOff1 = fOff2 = 0;

   fHotChar = 0;
   fHotPos  = 0;    // No hotkey defaults the offset to zero

   if (!s) return;

   char *dup = StrDup(s);
   char *p;

   for (p = dup; *p; p++) {
      if (*p == '&') {
         if (p[1] == '&') { // escaped & ?
            // copy the string down over it
            for (char *tmp = p; *tmp; tmp++)
               tmp[0] = tmp[1];
            continue; // and skip to the key char
         }
         // hot key marker - calculate the offset value
         fHotPos  = (p - dup) + 1;
         fHotChar = tolower(p[1]);
         for (; *p; p++) p[0] = p[1];  // copy down
         break;                        // allow only one hotkey per item
      }
   }
   Append(dup);
   delete [] dup;
}

//______________________________________________________________________________
void TGHotString::Draw(Drawable_t id, GContext_t gc, Int_t x, Int_t y)
{
   // Draw a hot string and underline the hot character.

   gVirtualX->DrawString(id, gc, x, y, Data(), Length());

   DrawHotChar(id, gc, x, y);
}

//______________________________________________________________________________
void TGHotString::DrawWrapped(Drawable_t id, GContext_t gc,
                              Int_t x, Int_t y, UInt_t w, FontStruct_t font)
{
   // Draw a hot string in a column with width w. If string is longer than
   // w wrap it to next line.

   const char *p     = Data();
   const char *prev  = p;
   const char *chunk = p;
   int tw, th, len = Length();

   tw = gVirtualX->TextWidth(font, p, len);
   if (tw <= (int)w) {
      gVirtualX->DrawString(id, gc, x, y, p, len);
      DrawHotChar(id, gc, x, y);
      return;
   }

   int max_ascent, max_descent;
   gVirtualX->GetFontProperties(font, max_ascent, max_descent);
   th = max_ascent + max_descent + 1;

   int pcnt = 0;
   while(1) {
      p = strchr(p, ' ');
      if (p == 0) {
         if (chunk) {
            gVirtualX->DrawString(id, gc, x, y, chunk, strlen(chunk));
            if (fHotPos > pcnt && fHotPos <= pcnt+(int)strlen(chunk))
               DrawHotChar(id, gc, x, y);
         }
         break;
      }
      tw = gVirtualX->TextWidth(font, chunk, p-chunk);
      if (tw > (int)w) {
         if (prev == chunk)
            prev = ++p;
         else
            p = prev;
         gVirtualX->DrawString(id, gc, x, y, chunk, prev-chunk-1);
         if (fHotPos > pcnt && fHotPos <= pcnt+prev-chunk-1)
            DrawHotChar(id, gc, x, y);
         pcnt = prev-chunk-1;
         chunk = prev;
         y += th;
      } else {
         prev = ++p;
      }
   }
}

//______________________________________________________________________________
void TGHotString::DrawHotChar(Drawable_t id, GContext_t gc, Int_t x, Int_t y)
{
   // Draw the underline under the hot character.

   if (fHotPos > 0) {
      if (fLastGC != gc) {
         GCValues_t   gcval;
         FontStruct_t font;

         gcval.fMask = kGCFont;
         gVirtualX->GetGCValues(gc, gcval);
         font = gVirtualX->GetFontStruct(gcval.fFont);

         fOff1   = gVirtualX->TextWidth(font, Data(), fHotPos-1); //+1;
         fOff2   = gVirtualX->TextWidth(font, Data(), fHotPos) - 1;

         gVirtualX->FreeFontStruct(font);
         fLastGC = gc;
      }
      gVirtualX->DrawLine(id, gc, x+fOff1, y+1, x+fOff2, y+1);
   }
}

 TGString.cxx:1
 TGString.cxx:2
 TGString.cxx:3
 TGString.cxx:4
 TGString.cxx:5
 TGString.cxx:6
 TGString.cxx:7
 TGString.cxx:8
 TGString.cxx:9
 TGString.cxx:10
 TGString.cxx:11
 TGString.cxx:12
 TGString.cxx:13
 TGString.cxx:14
 TGString.cxx:15
 TGString.cxx:16
 TGString.cxx:17
 TGString.cxx:18
 TGString.cxx:19
 TGString.cxx:20
 TGString.cxx:21
 TGString.cxx:22
 TGString.cxx:23
 TGString.cxx:24
 TGString.cxx:25
 TGString.cxx:26
 TGString.cxx:27
 TGString.cxx:28
 TGString.cxx:29
 TGString.cxx:30
 TGString.cxx:31
 TGString.cxx:32
 TGString.cxx:33
 TGString.cxx:34
 TGString.cxx:35
 TGString.cxx:36
 TGString.cxx:37
 TGString.cxx:38
 TGString.cxx:39
 TGString.cxx:40
 TGString.cxx:41
 TGString.cxx:42
 TGString.cxx:43
 TGString.cxx:44
 TGString.cxx:45
 TGString.cxx:46
 TGString.cxx:47
 TGString.cxx:48
 TGString.cxx:49
 TGString.cxx:50
 TGString.cxx:51
 TGString.cxx:52
 TGString.cxx:53
 TGString.cxx:54
 TGString.cxx:55
 TGString.cxx:56
 TGString.cxx:57
 TGString.cxx:58
 TGString.cxx:59
 TGString.cxx:60
 TGString.cxx:61
 TGString.cxx:62
 TGString.cxx:63
 TGString.cxx:64
 TGString.cxx:65
 TGString.cxx:66
 TGString.cxx:67
 TGString.cxx:68
 TGString.cxx:69
 TGString.cxx:70
 TGString.cxx:71
 TGString.cxx:72
 TGString.cxx:73
 TGString.cxx:74
 TGString.cxx:75
 TGString.cxx:76
 TGString.cxx:77
 TGString.cxx:78
 TGString.cxx:79
 TGString.cxx:80
 TGString.cxx:81
 TGString.cxx:82
 TGString.cxx:83
 TGString.cxx:84
 TGString.cxx:85
 TGString.cxx:86
 TGString.cxx:87
 TGString.cxx:88
 TGString.cxx:89
 TGString.cxx:90
 TGString.cxx:91
 TGString.cxx:92
 TGString.cxx:93
 TGString.cxx:94
 TGString.cxx:95
 TGString.cxx:96
 TGString.cxx:97
 TGString.cxx:98
 TGString.cxx:99
 TGString.cxx:100
 TGString.cxx:101
 TGString.cxx:102
 TGString.cxx:103
 TGString.cxx:104
 TGString.cxx:105
 TGString.cxx:106
 TGString.cxx:107
 TGString.cxx:108
 TGString.cxx:109
 TGString.cxx:110
 TGString.cxx:111
 TGString.cxx:112
 TGString.cxx:113
 TGString.cxx:114
 TGString.cxx:115
 TGString.cxx:116
 TGString.cxx:117
 TGString.cxx:118
 TGString.cxx:119
 TGString.cxx:120
 TGString.cxx:121
 TGString.cxx:122
 TGString.cxx:123
 TGString.cxx:124
 TGString.cxx:125
 TGString.cxx:126
 TGString.cxx:127
 TGString.cxx:128
 TGString.cxx:129
 TGString.cxx:130
 TGString.cxx:131
 TGString.cxx:132
 TGString.cxx:133
 TGString.cxx:134
 TGString.cxx:135
 TGString.cxx:136
 TGString.cxx:137
 TGString.cxx:138
 TGString.cxx:139
 TGString.cxx:140
 TGString.cxx:141
 TGString.cxx:142
 TGString.cxx:143
 TGString.cxx:144
 TGString.cxx:145
 TGString.cxx:146
 TGString.cxx:147
 TGString.cxx:148
 TGString.cxx:149
 TGString.cxx:150
 TGString.cxx:151
 TGString.cxx:152
 TGString.cxx:153
 TGString.cxx:154
 TGString.cxx:155
 TGString.cxx:156
 TGString.cxx:157
 TGString.cxx:158
 TGString.cxx:159
 TGString.cxx:160
 TGString.cxx:161
 TGString.cxx:162
 TGString.cxx:163
 TGString.cxx:164
 TGString.cxx:165
 TGString.cxx:166
 TGString.cxx:167
 TGString.cxx:168
 TGString.cxx:169
 TGString.cxx:170
 TGString.cxx:171
 TGString.cxx:172
 TGString.cxx:173
 TGString.cxx:174
 TGString.cxx:175
 TGString.cxx:176
 TGString.cxx:177
 TGString.cxx:178
 TGString.cxx:179
 TGString.cxx:180
 TGString.cxx:181
 TGString.cxx:182
 TGString.cxx:183
 TGString.cxx:184
 TGString.cxx:185
 TGString.cxx:186
 TGString.cxx:187
 TGString.cxx:188
 TGString.cxx:189
 TGString.cxx:190
 TGString.cxx:191
 TGString.cxx:192
 TGString.cxx:193
 TGString.cxx:194
 TGString.cxx:195
 TGString.cxx:196
 TGString.cxx:197
 TGString.cxx:198
 TGString.cxx:199
 TGString.cxx:200
 TGString.cxx:201
 TGString.cxx:202
 TGString.cxx:203
 TGString.cxx:204
 TGString.cxx:205
 TGString.cxx:206
 TGString.cxx:207
 TGString.cxx:208
 TGString.cxx:209
 TGString.cxx:210
 TGString.cxx:211
 TGString.cxx:212
 TGString.cxx:213
 TGString.cxx:214
 TGString.cxx:215
 TGString.cxx:216
 TGString.cxx:217
 TGString.cxx:218
 TGString.cxx:219
 TGString.cxx:220
 TGString.cxx:221
 TGString.cxx:222
 TGString.cxx:223
 TGString.cxx:224
 TGString.cxx:225
 TGString.cxx:226
 TGString.cxx:227
 TGString.cxx:228
 TGString.cxx:229
 TGString.cxx:230
 TGString.cxx:231
 TGString.cxx:232
 TGString.cxx:233
 TGString.cxx:234
 TGString.cxx:235
 TGString.cxx:236
 TGString.cxx:237
 TGString.cxx:238
 TGString.cxx:239
 TGString.cxx:240
 TGString.cxx:241
 TGString.cxx:242
 TGString.cxx:243
 TGString.cxx:244
 TGString.cxx:245
 TGString.cxx:246
 TGString.cxx:247
 TGString.cxx:248
 TGString.cxx:249
 TGString.cxx:250
 TGString.cxx:251