int SFontInstance::GetStringWidth( const char *pzString, int nLength ) { int nWidth = 0; g_cFontLock.Lock(); while( nLength > 0 ) { int nCharLen = utf8_char_length( *pzString ); if( nCharLen > nLength ) { break; } Glyph *pcGlyph = GetGlyph( FT_Get_Char_Index( m_pcFont->GetTTFace(), utf8_to_unicode( pzString ) ) ); pzString += nCharLen; nLength -= nCharLen; if( pcGlyph == NULL ) { dbprintf( "Error: GetStringWidth() failed to load glyph\n" ); continue; } nWidth += pcGlyph->m_nAdvance.x; } g_cFontLock.Unlock(); return ( nWidth ); }
void SFont::AddInstance( SFontInstance * pcInstance ) { g_cFontLock.Lock(); __assertw( g_cFontLock.IsLocked() ); m_cInstances[pcInstance->m_cInstanceProperties] = pcInstance; g_cFontLock.Unlock(); }
SFontInstance::SFontInstance( SFont * pcFont, const FontProperty & cFP ) { m_bFixedWidth = pcFont->IsFixedWidth(); g_cFontLock.Lock(); m_pcFont = pcFont; m_nGlyphCount = pcFont->GetGlyphCount(); if( m_nGlyphCount > 0 ) { m_ppcGlyphTable = new Glyph *[m_nGlyphCount]; memset( m_ppcGlyphTable, 0, m_nGlyphCount * sizeof( Glyph * ) ); } else { m_ppcGlyphTable = NULL; } m_cInstanceProperties = cFP; FT_Face psFace = m_pcFont->GetTTFace(); if( psFace->face_flags & FT_FACE_FLAG_SCALABLE ) { FT_Set_Char_Size( psFace, m_cInstanceProperties.m_nPointSize, m_cInstanceProperties.m_nPointSize, 96, 96 ); } else { FT_Set_Pixel_Sizes( psFace, 0, ( m_cInstanceProperties.m_nPointSize * 96 / 72 ) / 64 ); } FT_Size psSize = psFace->size; m_nNomWidth = psSize->metrics.x_ppem; m_nNomHeight = psSize->metrics.y_ppem; if( psSize->metrics.descender > 0 ) { m_nDescender = -( psSize->metrics.descender + 63 ) / 64; // m_nLineGap = (psSize->metrics.height - (psSize->metrics.ascender + psSize->metrics.descender) + 63) / 64; } else { m_nDescender = ( psSize->metrics.descender + 63 ) / 64; // m_nLineGap = (psSize->metrics.height - (psSize->metrics.ascender - psSize->metrics.descender) + 63) / 64; } m_nAscender = ( psSize->metrics.ascender + 63 ) / 64; m_nLineGap = ( psSize->metrics.height + 63 ) / 64 - ( m_nAscender - m_nDescender ); m_nAdvance = ( psSize->metrics.max_advance + 63 ) / 64; // printf( "Size1(%d): %ld, %ld, %ld (%ld, %ld, %ld)\n", nPointSize, psSize->metrics.ascender, psSize->metrics.descender, psSize->metrics.height, // psSize->metrics.ascender / 64, psSize->metrics.descender / 64, psSize->metrics.height / 64 ); // Register our self with the font m_pcFont->AddInstance( this ); g_cFontLock.Unlock(); }
int FontServer::GetFamilyCount() const { int nCount; g_cFontLock.Lock(); nCount = m_cFamilies.size(); g_cFontLock.Unlock(); return ( nCount ); }
status_t SFontInstance::SetProperties( const FontProperty & cFP ) { g_cFontLock.Lock(); m_pcFont->RemoveInstance( this ); m_cInstanceProperties = cFP; FT_Face psFace = m_pcFont->GetTTFace(); if( psFace->face_flags & FT_FACE_FLAG_SCALABLE ) { FT_Set_Char_Size( psFace, m_cInstanceProperties.m_nPointSize, m_cInstanceProperties.m_nPointSize, 96, 96 ); } else { FT_Set_Pixel_Sizes( psFace, 0, ( m_cInstanceProperties.m_nPointSize * 96 / 72 ) / 64 ); } FT_Size psSize = psFace->size; m_nNomWidth = psSize->metrics.x_ppem; m_nNomHeight = psSize->metrics.y_ppem; if( psSize->metrics.descender > 0 ) { m_nDescender = -( psSize->metrics.descender + 63 ) / 64; // m_nLineGap = (psSize->metrics.height - (psSize->metrics.ascender + psSize->metrics.descender) + 63) / 64; } else { m_nDescender = ( psSize->metrics.descender + 63 ) / 64; // m_nLineGap = (psSize->metrics.height - (psSize->metrics.ascender - psSize->metrics.descender) + 63) / 64; } m_nAscender = ( psSize->metrics.ascender + 63 ) / 64; m_nLineGap = ( psSize->metrics.height + 63 ) / 64 - ( m_nAscender - m_nDescender ); m_nAdvance = ( psSize->metrics.max_advance + 63 ) / 64; // printf( "Size2(%d): %ld, %ld, %ld (%ld, %ld, %ld)\n", nPointSize, psSize->metrics.ascender, psSize->metrics.descender, psSize->metrics.height, // psSize->metrics.ascender / 64, psSize->metrics.descender / 64, psSize->metrics.height / 64 ); for( int i = 0; i < m_nGlyphCount; ++i ) { if( m_ppcGlyphTable[i] != NULL ) { delete[]reinterpret_cast < char *>( m_ppcGlyphTable[i] ); m_ppcGlyphTable[i] = NULL; } } m_pcFont->AddInstance( this ); g_cFontLock.Unlock(); return ( 0 ); }
SFontInstance::~SFontInstance() { g_cFontLock.Lock(); m_pcFont->RemoveInstance( this ); for( int i = 0; i < m_nGlyphCount; ++i ) { delete[]reinterpret_cast < char *>( m_ppcGlyphTable[i] ); } delete[]m_ppcGlyphTable; g_cFontLock.Unlock(); }
int FontServer::GetStyle( const std::string & cFamily, int nIndex, char *pzStyle, uint32 *pnFlags ) const { int nError = 0; g_cFontLock.Lock(); FontFamily *pcFamily = FindFamily( cFamily ); if( pcFamily != NULL ) { if( nIndex < int ( pcFamily->m_cFonts.size() ) ) { std::map <std::string, SFont * >::const_iterator i = pcFamily->m_cFonts.begin(); while( nIndex-- > 0 ) ++i; strcpy( pzStyle, ( *i ).first.c_str() ); *pnFlags = 0; if( ( *i ).second->IsFixedWidth() ) { *pnFlags |= FONT_IS_FIXED; } if( ( *i ).second->IsScalable() ) { *pnFlags |= FONT_IS_SCALABLE; if( ( *i ).second->GetBitmapSizes().size( ) > 0 ) { *pnFlags |= FONT_HAS_TUNED_SIZES; } } else { *pnFlags |= FONT_HAS_TUNED_SIZES; } nError = 0; } else { nError = EINVAL; } } else { nError = ENOENT; } g_cFontLock.Unlock(); return ( nError ); }
int FontServer::GetStyleCount( const std::string & cFamily ) const { int nCount = -1; g_cFontLock.Lock(); FontFamily *pcFamily = FindFamily( cFamily ); if( pcFamily != NULL ) { nCount = pcFamily->m_cFonts.size(); } g_cFontLock.Unlock(); return ( nCount ); }
int FontServer::GetFamily( int nIndex, char *pzFamily, uint32 *pnFlags ) { int nError = EINVAL; g_cFontLock.Lock(); if( nIndex < int ( m_cFamilies.size() ) ) { std::map <std::string, FontFamily * >::const_iterator i = m_cFamilies.begin(); while( nIndex-- > 0 ) ++i; strcpy( pzFamily, ( *i ).first.c_str() ); nError = 0; } g_cFontLock.Unlock(); return ( nError ); }
void SFont::RemoveInstance( SFontInstance * pcInstance ) { g_cFontLock.Lock(); std::map <FontProperty, SFontInstance * >::iterator i; __assertw( g_cFontLock.IsLocked() ); i = m_cInstances.find( pcInstance->m_cInstanceProperties ); if( i != m_cInstances.end() ) { m_cInstances.erase( i ); } else { dbprintf( "Error: SFont::RemoveInstance could not find instance\n" ); } if( m_bDeleted && m_cInstances.empty() ) { dbprintf( "Last instance of deleted font %s, %s removed. Deleting font\n", m_pcFamily->GetName().c_str( ), m_cStyle.c_str( ) ); delete this; } g_cFontLock.Unlock(); }
int SFontInstance::GetStringLength( const char *pzString, int nLength, int nWidth, bool bIncludeLast ) { int nStrLen = 0; g_cFontLock.Lock(); while( nLength > 0 ) { int nCharLen = utf8_char_length( *pzString ); if( nCharLen > nLength ) { break; } Glyph *pcGlyph = GetGlyph( FT_Get_Char_Index( m_pcFont->GetTTFace(), utf8_to_unicode( pzString ) ) ); if( pcGlyph == NULL ) { dbprintf( "Error: GetStringLength() failed to load glyph\n" ); break; } if( nWidth < pcGlyph->m_nAdvance.x ) { if( bIncludeLast ) { nStrLen += nCharLen; } break; } pzString += nCharLen; nLength -= nCharLen; nStrLen += nCharLen; nWidth -= pcGlyph->m_nAdvance.x; } g_cFontLock.Unlock(); return ( nStrLen ); }
SFontInstance *FontServer::OpenInstance( const std::string & cFamily, const std::string & cStyle, const FontProperty & cFP ) { FontFamily *pcFamily; g_cFontLock.Lock(); if( ( pcFamily = FindFamily( cFamily ) ) ) { SFont *pcFont = pcFamily->FindStyle( cStyle ); if( pcFont != NULL ) { SFontInstance *pcInstance = pcFont->OpenInstance( cFP ); if( pcInstance != NULL ) { g_cFontLock.Unlock(); return ( pcInstance ); } } } g_cFontLock.Unlock(); return ( NULL ); }
IPoint SFontInstance::GetTextExtent( const char *pzString, int nLength, uint32 nFlags, int nTargetWidth ) { IPoint cExt( 0, m_nAscender - m_nDescender ); if( ( nFlags & DTF_WRAP_SOFT ) && ( nTargetWidth <= 0 ) ) return cExt; g_cFontLock.Lock(); // Count rows. int i, nCharLength = 0; const char *p = pzString; std::list<int> vRowLens; if( nFlags & DTF_WRAP_SOFT ) { int nWordWidth = 0, nLineWidth = 0; // Width of word/line in pixels int nWordLength = 0, nLineLength = 0; // Length of word/line in bytes for( i = nLength; i > 0; p += nCharLength ) { // Get char length nCharLength = utf8_char_length( *p ); nWordLength += nCharLength; i -= nCharLength; // Get glyph width Glyph *pcGlyph = GetGlyph( FT_Get_Char_Index( m_pcFont->GetTTFace(), utf8_to_unicode( p ) ) ); if( NULL == pcGlyph ) continue; nWordWidth += pcGlyph->m_nAdvance.x; if( *p == ' ' || *p == '\t' || *p == '\n' ) { if( nLineWidth + nWordWidth > nTargetWidth ) { // Start a new line before this word vRowLens.push_back( nLineLength ); nLineWidth = nWordWidth; nLineLength = nWordLength; } else { // Continue the current line nLineWidth += nWordWidth; nLineLength += nWordLength; if( *p == '\n' ) { // Start a newline after this word vRowLens.push_back( nLineLength ); nLineWidth = nLineLength = 0; } } nWordWidth = nWordLength = 0; } } // Push back the last line. vRowLens.push_back( nLineLength ); } else vRowLens.push_back( nLength ); int nOffset = 0, nLineExtent; std::list<int>::iterator l; for( l = vRowLens.begin(); l != vRowLens.end(); l++ ) { int nLineLength = (*l); const char *pzLine = pzString + nOffset; nLineExtent = 0; while( nLineLength > 0 ) { if( !( nFlags & DTF_IGNORE_FMT ) ) { bool bDone; do { bDone = false; switch ( *pzLine ) { case '_': { if( !( nFlags & DTF_UNDERLINES ) ) bDone = true; else { pzLine++; nLineLength--; } break; } case '\n': { if( !( nFlags & DTF_WRAP_SOFT ) ) { cExt.y += m_nAscender - m_nDescender + m_nLineGap; if( nLineExtent > cExt.x ) cExt.x = nLineExtent; nLineExtent = 0; } pzLine++; nLineLength--; break; } case '\t': { int nSkip = TAB_STOP - int( cExt.x ) % TAB_STOP; if( nSkip < 2 ) nSkip = TAB_STOP; cExt.x += nSkip; pzLine++; nLineLength--; break; } case 27: { pzLine++; nLineLength--; if( nLineLength > 0 && *pzLine != '[' ) { pzLine++; nLineLength--; } break; } default: bDone = true; } // switch() } while( nLineLength > 0 && !bDone ); } // if() int nCharLen = utf8_char_length( *pzLine ); if( nCharLen > nLineLength ) break; Glyph *pcGlyph = GetGlyph( FT_Get_Char_Index( m_pcFont->GetTTFace(), utf8_to_unicode( pzLine ) ) ); pzLine += nCharLen; nLineLength -= nCharLen; if( pcGlyph == NULL ) { dbprintf( "Error: GetTextExtent() failed to load glyph\n" ); continue; } nLineExtent += pcGlyph->m_nAdvance.x; } // while() if( nLineExtent > cExt.x ) cExt.x = nLineExtent; if( nFlags & DTF_WRAP_SOFT ) cExt.y += m_nAscender - m_nDescender + m_nLineGap; nOffset += (*l); } // for() g_cFontLock.Unlock(); return ( cExt ); }
void FontServer::ScanDirectory( const char *pzPath ) { DIR *hDir; dirent *psEntry; g_cFontLock.Lock(); std::map <std::string, FontFamily * >::iterator cFamIter; for( cFamIter = m_cFamilies.begin(); cFamIter != m_cFamilies.end( ); ++cFamIter ) { std::map <std::string, SFont * >::iterator cStyleIter; for( cStyleIter = ( *cFamIter ).second->m_cFonts.begin(); cStyleIter != ( *cFamIter ).second->m_cFonts.end( ); ++cStyleIter ) { ( *cStyleIter ).second->SetDeletedFlag( true ); } } if( ( hDir = opendir( pzPath ) ) ) { int nCount = 0; while( ( psEntry = readdir( hDir ) ) ) { FT_Face psFace; FT_Error nError; char zFullPath[PATH_MAX]; if( strcmp( psEntry->d_name, "." ) == 0 || strcmp( psEntry->d_name, ".." ) == 0 ) { continue; } strcpy( zFullPath, pzPath ); pathcat( zFullPath, psEntry->d_name ); nError = FT_New_Face( m_hFTLib, zFullPath, 0, &psFace ); if( nError != 0 ) { continue; } FT_CharMap psCharMap; int i; for( i = 0; i < psFace->num_charmaps; i++ ) { psCharMap = psFace->charmaps[i]; if( psCharMap->platform_id == 3 && psCharMap->encoding_id == 1 ) { // Windows unicode goto found; } } for( i = 0; i < psFace->num_charmaps; i++ ) { psCharMap = psFace->charmaps[i]; if( psCharMap->platform_id == 1 && psCharMap->encoding_id == 0 ) { // Apple unicode goto found; } } for( i = 0; i < psFace->num_charmaps; i++ ) { psCharMap = psFace->charmaps[i]; if( psCharMap->platform_id == 3 && psCharMap->encoding_id == 0 ) { // Windows symbol goto found; } } for( i = 0; i < psFace->num_charmaps; i++ ) { psCharMap = psFace->charmaps[i]; if( psCharMap->platform_id == 0 && psCharMap->encoding_id == 0 ) { // Apple roman goto found; } } for( i = 0; i < psFace->num_charmaps; i++ ) { psCharMap = psFace->charmaps[i]; dbprintf( "platform=%d, encoding=%d\n", psCharMap->platform_id, psCharMap->encoding_id ); } FT_Done_Face( psFace ); dbprintf( "Error: failed to find character map\n" ); continue; found: psFace->charmap = psCharMap; FontFamily *pcFamily = FindFamily( psFace->family_name ); if( NULL == pcFamily ) { try { pcFamily = new FontFamily( psFace->family_name ); } catch( ... ) { continue; } m_cFamilies[psFace->family_name] = pcFamily; } SFont *pcFont = pcFamily->FindStyle( psFace->style_name ); if( pcFont != NULL ) { pcFont->SetDeletedFlag( false ); FT_Done_Face( psFace ); continue; } else { try { pcFont = new SFont( pcFamily, psFace ); } catch( ... ) { continue; } } __assertw( NULL != pcFont ); #if 0 dbprintf( "Font : '%s'-'%s' (%d) added\n", psFace->family_name, psFace->style_name, psFace->num_fixed_sizes ); if( psFace->num_fixed_sizes > 0 ) { for( int j = 0; j < psFace->num_fixed_sizes; ++j ) { dbprintf( " Size %d : %dx%d\n", j, psFace->available_sizes[j].width, psFace->available_sizes[j].height ); } } #endif nCount++; } dbprintf( "Directory '%s' scanned %d fonts found\n", pzPath, nCount ); closedir( hDir ); } restart: for( cFamIter = m_cFamilies.begin(); cFamIter != m_cFamilies.end( ); ++cFamIter ) { std::map <std::string, SFont * >::iterator cStyleIter; for( cStyleIter = ( *cFamIter ).second->m_cFonts.begin(); cStyleIter != ( *cFamIter ).second->m_cFonts.end( ); ++cStyleIter ) { SFont *pcStyle = ( *cStyleIter ).second; if( pcStyle->IsDeleted() && pcStyle->GetInstanceCount( ) == 0 ) { dbprintf( "Deleting font %s:%s\n", pcStyle->GetFamily()->GetName( ).c_str( ), pcStyle->GetStyle( ).c_str( ) ); delete pcStyle; goto restart; } } } g_cFontLock.Unlock(); }
bool FontServer::Lock() { return ( g_cFontLock.Lock() == 0 ); }
BrowserWindow::BrowserWindow( const Rect &cFrame ) : Window( cFrame, "webview_wnd", "Webster" ) { Rect cMenuFrame, cToolFrame, cStatusFrame, cTabFrame; m_pcChromeClient = new BrowserChromeClient( this ); m_pcWebSettings = new WebSettings(); m_pcWebSettings->Load(); m_pcSettings = new Settings(); m_pcSettings->Load(); /* Get window layouts */ m_pcGuiSettings = new Settings(); m_pcGuiSettings->SetFile( "Gui" ); m_pcGuiSettings->Load(); m_cWindowFrame = m_pcGuiSettings->GetRect( "webster", cFrame ); m_cSettingsFrame = m_pcGuiSettings->GetRect( "settings", Rect( 25, 25, 600, 450 ) ); SetFrame( m_cWindowFrame ); cMenuFrame = cToolFrame = cStatusFrame = cTabFrame = GetBounds(); /* DANGER WILL ROBINSON! See the note in the BrowserApp constructor about this mutex! */ g_cGlobalMutex.Lock(); SetMutex( &g_cGlobalMutex ); m_pcMenuBar = new Menu( cMenuFrame, "menubar", ITEMS_IN_ROW ); Menu *pcApplicationMenu = new Menu( Rect(), "Application", ITEMS_IN_COLUMN ); pcApplicationMenu->AddItem( "Quit", new Message( M_TERMINATE ), "Ctrl+Q" ); pcApplicationMenu->AddItem( new MenuSeparator() ); pcApplicationMenu->AddItem( "About Webster", new Message( ID_MENU_APP_ABOUT ) ); m_pcMenuBar->AddItem( pcApplicationMenu ); Menu *pcWindowMenu = new Menu( Rect(), "Window", ITEMS_IN_COLUMN ); pcWindowMenu->AddItem( "New window", new Message( ID_CREATE_WINDOW ), "Ctrl+N" ); pcWindowMenu->AddItem( "Close window", new Message( M_QUIT ), "Ctrl+W" ); pcWindowMenu->AddItem( new MenuSeparator() ); pcWindowMenu->AddItem( "New tab", new Message( ID_MENU_WIN_NEW_TAB ), "Ctrl+T" ); pcWindowMenu->AddItem( "Close tab", new Message( ID_MENU_WIN_CLOSE_TAB ) ); m_pcMenuBar->AddItem( pcWindowMenu ); Menu *pcEditMenu = new Menu( Rect(), "Edit", ITEMS_IN_COLUMN ); pcEditMenu->AddItem( "Cut", new Message( ID_MENU_EDIT_CUT ), "Ctrl+X" ); pcEditMenu->AddItem( "Copy", new Message( ID_MENU_EDIT_COPY ), "Ctrl+C" ); pcEditMenu->AddItem( "Paste", new Message( ID_MENU_EDIT_PASTE ), "Ctrl+V" ); pcEditMenu->AddItem( new MenuSeparator() ); pcEditMenu->AddItem( "Delete", new Message( ID_MENU_EDIT_DELETE ) ); m_pcMenuBar->AddItem( pcEditMenu ); Menu *pcSettingsMenu = new Menu( Rect(), "Settings", ITEMS_IN_COLUMN ); pcSettingsMenu->AddItem( "Configure", new Message( ID_MENU_SETTINGS_CONFIGURE ) ); m_pcMenuBar->AddItem( pcSettingsMenu ); m_pcBookmarksManager = new BookmarksManager(); BookmarksMenu *pcBookmarksMenu = m_pcBookmarksManager->CreateMenu( "Bookmarks", Path( "" ) ); m_pcMenuBar->AddItem( pcBookmarksMenu ); m_pcMenuBar->SetTargetForItems( this ); cMenuFrame.bottom = m_pcMenuBar->GetPreferredSize( false ).y; m_pcMenuBar->SetFrame( cMenuFrame ); AddChild( m_pcMenuBar ); /* Setup the toolbar */ bool bShowButtonText = m_pcSettings->GetBool( "show_button_text", true ); m_pcToolBar = new ToolBar( Rect(), "toolbar", CF_FOLLOW_LEFT | CF_FOLLOW_RIGHT | CF_FOLLOW_TOP ); ResStream *pcStream; File cSelf( open_image_file( get_image_id() ) ); Resources cCol( &cSelf ); m_pcBackButton = new ImageButton( Rect(), "back", "Back", new Message(ID_BUTTON_BACK), NULL, ImageButton::IB_TEXT_BOTTOM, true, bShowButtonText, true ); pcStream = cCol.GetResourceStream( "back.png" ); m_pcBackButton->SetImage( pcStream ); delete( pcStream ); m_pcForwardButton = new ImageButton( Rect(), "foward", "Forward", new Message(ID_BUTTON_FORWARD), NULL, ImageButton::IB_TEXT_BOTTOM, true, bShowButtonText, true ); pcStream = cCol.GetResourceStream( "forward.png" ); m_pcForwardButton->SetImage( pcStream ); delete( pcStream ); m_pcReloadButton = new ImageButton( Rect(), "reload", "Reload", new Message(ID_BUTTON_RELOAD), NULL, ImageButton::IB_TEXT_BOTTOM, true, bShowButtonText, true ); pcStream = cCol.GetResourceStream( "reload.png" ); m_pcReloadButton->SetImage( pcStream ); delete( pcStream ); m_pcStopButton = new ImageButton( Rect(), "stop", "Stop", new Message(ID_BUTTON_STOP), NULL, ImageButton::IB_TEXT_BOTTOM, true, bShowButtonText, true ); pcStream = cCol.GetResourceStream( "stop.png" ); m_pcStopButton->SetImage( pcStream ); delete( pcStream ); m_pcHomeButton = new ImageButton( Rect(), "home", "Home", new Message(ID_BUTTON_HOME), NULL, ImageButton::IB_TEXT_BOTTOM, true, bShowButtonText, true ); pcStream = cCol.GetResourceStream( "home.png" ); m_pcHomeButton->SetImage( pcStream ); delete( pcStream ); m_pcBackButton->SetEnable( false ); m_pcForwardButton->SetEnable( false ); m_pcStopButton->SetEnable( false ); m_pcToolBar->AddChild( m_pcBackButton, ToolBar::TB_FIXED_WIDTH ); m_pcToolBar->AddChild( m_pcForwardButton, ToolBar::TB_FIXED_WIDTH ); m_pcToolBar->AddChild( m_pcReloadButton, ToolBar::TB_FIXED_WIDTH ); m_pcToolBar->AddChild( m_pcStopButton, ToolBar::TB_FIXED_WIDTH ); m_pcToolBar->AddChild( m_pcHomeButton, ToolBar::TB_FIXED_WIDTH ); m_pcUrlEdit = new UrlEdit( Rect(), "urledit", CF_FOLLOW_LEFT | CF_FOLLOW_RIGHT | CF_FOLLOW_TOP ); m_pcUrlEdit->SetMinPreferredSize( 32 ); m_pcUrlEdit->SetMaxPreferredSize( 256 ); m_pcUrlEdit->SetEditMessage( new Message( ID_URL_CHANGED ) ); m_pcUrlEdit->SetSelectionMessage( new Message( ID_URL_CHANGED ) ); m_pcUrlEdit->SetTarget( this, this ); m_pcToolBar->AddChild( m_pcUrlEdit, ToolBar::TB_FREE_WIDTH ); cToolFrame.top = cMenuFrame.bottom + 1.0f; cToolFrame.bottom = cToolFrame.top + m_pcToolBar->GetPreferredSize(false).y; m_pcToolBar->SetFrame( cToolFrame ); AddChild( m_pcToolBar ); m_pcStatusBar = new StatusBar( Rect(), "statusbar", CF_FOLLOW_LEFT | CF_FOLLOW_RIGHT | CF_FOLLOW_BOTTOM ); m_pcStatusBar->AddPanel( "text", "" ); m_pcProgress = new ProgressPanel( "progress", 10 ); m_pcStatusBar->AddPanel( m_pcProgress ); cStatusFrame.top = cStatusFrame.bottom - 20; m_pcStatusBar->SetFrame( cStatusFrame ); AddChild( m_pcStatusBar ); cTabFrame.top = cToolFrame.bottom + 1.0f; cTabFrame.bottom = cStatusFrame.top - 1.0f; m_pcTabView = new TabView( cTabFrame, "webviewtabs", CF_FOLLOW_ALL ); m_pcTabView->SetMessage( new Message( ID_TAB_CHANGED ) ); AddChild( m_pcTabView ); /* Create a tab and open the homepage, if one is configured */ CreateTab( m_pcSettings->GetString( "homepage", "about:blank" ) ); /* Set Window icon */ pcStream = cCol.GetResourceStream( "icon24x24.png" ); BitmapImage *pcIcon = new BitmapImage( pcStream ); delete( pcStream ); SetIcon( pcIcon->LockBitmap() ); delete( pcIcon ); /* Nothing is being loaded at this point */ UpdateButtonState( false ); }