About Store Forum Documentation Contact
Donations:
158$/mo



Post Reply 
Berkelium Gui element
Author Message
yvanvds Offline
Silver Supporter

Post: #1
Berkelium Gui element
Hi!

Here's the code for a berkelium gui element. It can be used to add browser windows to your app. Most of the code is borrowed from rndbit and andargor. they had a discussion about this in the offtopic section. I've combined the parts of the code there and added a bit of my own. So here's webwindow struct you can use as a more or less complete solution. It supports multiple browser windows, mouse and keyboard input. I've also added a small tutorial file.

What is not done?
* not all input keys are handled. (The arrow keys are not, for example)
* function handlers for back and forward navigation should be added
* it's not possible to resize the element. It shouldn't be hard to implement, but I don't need it for now.

Anyway, here's the code:

PHP Code:
/* stdafx.h: be sure to include berkelium before esenthel
   Also adjust library and include paths for berkelium, and put the 
   needed dll and berkelium exe in your exe directory
*/
/******************************************************************************/
#include <berkelium/Berkelium.hpp>
#include <berkelium/Context.hpp>
#include <berkelium/Window.hpp>
#include <berkelium/WindowDelegate.hpp>
#include <EsenthelEngine/EsenthelEngine.h>
/******************************************************************************/

/* main.cpp: the main program, use this like an EE tutorial
   A browser element gets focused if you click on it.
*/
/******************************************************************************/
#include "stdafx.h"
#include "webwindow.h"

// we'll create 2 browsers in this tutorial
webWindow Web1;
webWindow Web2;

void InitPre() {
  
App.name("Berkelium");
  
Paks.add("data/engine.pak");
  
D.sync(true);
}

Bool Init() {
  
Web1.create(Rect(-D.w(),0,D.w(),D.h()), "http://www.google.com");
  
Web2.create(Rect(-D.w(),-D.h(),D.w(),0), "http://attr-x.net");
  
Gui += Web1;
  
Gui += Web2;

  return 
true;
}

void Shut() {}

Bool Update() {
  if(
Kb.bp(KB_ESC  ))return false;

  
Gui.update();
  return 
true;
}

void Draw() {
  
D.clear(BLACK); 
  
Gui.draw();
}
/******************************************************************************/

/* webwindow.h: contains a struct extending a GuiImage with a browser 
   contains a nested class for berkelium callbacks
*/
/******************************************************************************/


struct webWindow GuiImage {
  
Image            imgcube;
  
Berkelium::Window*  window;
  
Berkelium::Context*  context;
  
VecI2            size;
  
Int               wheel;

  
webWindow();
 ~
webWindow();

  
void         create(RectrStr8 url);
  
virtual void update(GuiPC &gpc);
  
virtual void draw  (GuiPC &pgc);
  
void         handleEvents();

  
// declaration of draw function where onpaint goes
  
void DrawBerkelium(Berkelium::Window            *win                    ,
                     const 
unsigned char        *sourceBuffer            ,
                     const 
Berkelium::Rect      &sourceBufferRect        ,
                     
size_t                         numCopyRects            ,
                     const 
Berkelium::Rect      *copyRects                ,
                     
int                         dx                     
                     
int                         dy                     ,
                     const 
Berkelium::Rect      &scrollRect                );
    
  
friend class MyDelegate;

  
// Berkelium callback class
  
class MyDelegate : public Berkelium::WindowDelegate {
    
webWindow self;
  public:
    
MyDelegate(webWindow window) : self(window) {}

    
virtual void onStartLoading(Berkelium::Window *winBerkelium::URLString newURL) {
      
Int i=0;
    }

    
virtual void onPaint(Berkelium::Window     *win             ,
                         const 
unsigned char   *sourceBuffer    ,
                         const 
Berkelium::Rect &sourceBufferRect,
                         
size_t                 numCopyRects    ,
                         const 
Berkelium::Rect *copyRects       ,
                         
int                    dx              
                         
int                    dy              ,
                         const 
Berkelium::Rect &scrollRect) {
      
self->DrawBerkelium(win,sourceBuffer,sourceBufferRect,numCopyRects,copyRects,dx,dy,scrollRect);
    }
  };
};

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

/* webwindow.cpp: the rest of the berkelium code and handler for key and
   mouse events
*/
/******************************************************************************/

#include "stdafx.h"
#include "webwindow.h"

UInt __berkeliumWindows 0;

UInt berkTxtBtns[][3] = {
  { 
KB_ENTER  13        },
  { 
KB_ESC    27        },
  { 
KB_DEL    0x2E      },
  { 
KB_NPENTER13        },
  { 
KB_BACK   , (UInt)'\b'}
};

UInt berkSpecBtns[][3] = {
  { 
KB_TAB, (UInt)'\t'}
};

// DrawBerkelium, code ripped from rndbit :D
void webWindow::DrawBerkelium(    Berkelium::Window     *win,    
                                const 
unsigned char      *sourceBuffer
                                const 
Berkelium::Rect &sourceBufferRect,
                                
size_t                 numCopyRects       ,
                                const 
Berkelium::Rect *copyRects       ,
                                
int                    dx              
                                
int                       dy              ,
                                const 
Berkelium::Rect &scrollRect        ) {

  if(!
imgcube.is()) {
    
imgcube.create2D(size.x,size.y,IMAGE_B8G8R8A8);
  }

  
imgcube.lock();

  
unsigned chartexd imgcube.data();
  
UInt tp imgcube.pitch();
  
UInt tw imgcube.x    ();
  
UInt th imgcube.y    ();
  
UInt sz tw*th*4;
    
  
// scrolling
  
{
    
Int wid  scrollRect.width ();
    
Int hig  scrollRect.height();
    
Int top  scrollRect.top   ();
    
Int left scrollRect.left  ();

    if(
dy 0) {   // scroll down
      
for (int y = -dyhigy++) {
        
UInt tb = ((top y) * tw left) * 4;
        
UInt tb2 tb dy tw 4;
        if (
tb >= && tb sz && tb2 >= && tb2 sz
                
memcpy(&texd[tb2], &texd[tb], wid 4);
      }
    }
    else if(
dy 0) {   // scroll up
      
for (int y hig dy> -1y--) {
        
UInt tb = ((top y) * tw left) * 4;
        
UInt tb2 tb dy tw 4;
        if (
tb >= && tb sz && tb2 >= && tb2 sz
                
memcpy(&texd[tb2], &texd[tb], wid 4);
      }
    }

    if(
dx != 0) {    // scroll
      
int subx dx : -dx;
      for (
int y 0higy++) {
        
UInt tb = ((top y) * tw left) * 4;
        
UInt tb2 tb dx 4;
        if (
tb >= && tb sz && tb2 >= && tb2 sz
                
memcpy(&texd[tb], &texd[tb2], wid subx);
      }
    }
  }

  
// copy new rects
  
for(UInt i 0numCopyRectsi++) {
    
Berkelium::Rect cr copyRects[i];
    
Int wid cr.width();
    
Int hig cr.height();
    
Int top cr.top() - sourceBufferRect.top();
    
Int left cr.left() - sourceBufferRect.left();

    for(
int y 0higy++) {
      
UInt tb = ((cr.top() + y) * tp cr.left()* 4) ;
            
UInt tb2 = (left + (top) * sourceBufferRect.width()) * 4;
      
memcpy(&texd[tb], &sourceBuffer[tb2], wid 4);
    }
  }

  
imgcube.unlock();
}

webWindow::webWindow() {
    
window NULL;
    
context NULL;
}

webWindow::~webWindow() {
  
window->destroy();
  
context->destroy();
  
__berkeliumWindows--;
  if (
__berkeliumWindows == 0) {
    
Berkelium::destroy();
  }
}

void webWindow::create(RectrStr8 url) {
  
size D.screenToPixel(r.rd()) - D.screenToPixel(r.lu());
    
  
// only initialize on first window
  
if (__berkeliumWindows == 0) {
    
Berkelium::init(Berkelium::FileString::empty());
  }
  
__berkeliumWindows++;

  
context Berkelium::Context::create();
  
window  Berkelium::Window::create(context);
  
window->resize     (size.xsize.y        );
  
window->setDelegate( new MyDelegate(this) ); // set callback class
  
window->focus      (                      ); 
  
window->navigateTo (url(), url.length()   );
  
super::create(r, &imgcube);
}

void webWindow::update(GuiPC &gpc) {
  
Berkelium::update();
  
handleEvents();
  
super::update(gpc);
}

void webWindow::draw(GuiPC &gpc) {
  
super::draw(gpc);
}

void webWindow::handleEvents() {
  if (
Cuts(Ms.pos(), T.rect)) {
    
// send mouse position
    
VecI2 pos D.screenToPixel(Ms.pos()) - D.screenToPixel(T.pos());
    
window->mouseMoved(pos.xpos.y);

    
// send mouse clicks and activate object if clicked
    
if(Ms.b(0)) {
      
window->mouseButton(0true);
      
T.activate();
    }
    if(
Ms.b(1)) {
      
window->mouseButton(1true);
      
T.activate();
    }
    if(
Ms.br(0)) window->mouseButton(0false);
    if(
Ms.br(1)) window->mouseButton(1false);

    
// send mouse wheel
    
if (Ms.wheel()!= 0) {
      
wheel Ms.wheel() * 20;
      
window->mouseWheel(0wheel);
    } else {
      
//smooth mouse wheel
      
if (wheel 0wheel--;
      else if (
wheel 0wheel++;
      
window->mouseWheel(0wheel);
    }
  }

  
// send keys if this object has keyboard focus
  
int mods 0;
  static 
UInt kbRepeatTimeout 300;
  if (
Gui.ms() == this) {
    while (const 
Char8 c Kb.c()) {
      if (
== ' ' || == 127 || >= 'a' && <= 'z' || >= 'A' && <= 'Z') {
        
window->keyEvent(truemodsc0);
      }
      
Char outchars[2] = { c0};
      
window->textEvent(outchars1);
      
Kb.nextBufferedChar();
    }
        
    for (
U32 i 0Elms(berkTxtBtns); i++) {
      
Bool bp Kb.bp((KB_BUTTON)berkTxtBtns[i][0]);
      
UInt timeDiff Time.curTimeMs() - berkTxtBtns[i][2];
      if (
bp || (Kb.b((KB_BUTTON)berkTxtBtns[i][0]) && timeDiff kbRepeatTimeout)) {
        if (!
bp || timeDiff 100kbRepeatTimeout 30;
        else 
kbRepeatTimeout 300;
        
window->keyEvent(truemodsberkTxtBtns[i][1], 0);
        
Char outchars[2] = {berkTxtBtns[i][1], };
        
window->textEvent(outchars1);
        
berkTxtBtns[i][2] = Time.curTimeMs();
      }
    }

    for (
U32 i 0Elms(berkSpecBtns); i++) {
      
Bool bp Kb.bp((KB_BUTTON)berkSpecBtns[i][0]);
      
UInt timeDiff Time.curTimeMs() - berkSpecBtns[i][2];
      if (
bp || (Kb.b((KB_BUTTON)berkSpecBtns[i][0]) && timeDiff kbRepeatTimeout)) {
        if (!
bp || timeDiff 100kbRepeatTimeout 30;
        else 
kbRepeatTimeout 300;
        
window->keyEvent(truemodsberkSpecBtns[i][1], 0);
      }
    }

    
Kb.eat();    
  }

09-14-2011 01:12 PM
Find all posts by this user Quote this message in a reply
aceio76 Offline
Silver Supporter

Post: #2
RE: Berkelium Gui element
This is great stuff! I was just looking into doing this over the weekend. I'm glad I came across this before I attempted my own. Thanks mate!

www.thinkplaystudios.com
09-27-2011 05:11 PM
Visit this user's website Find all posts by this user Quote this message in a reply
rndbit Offline
Member

Post: #3
RE: Berkelium Gui element
good to see my buggy code was useful smile
10-10-2011 10:42 AM
Find all posts by this user Quote this message in a reply
Post Reply