Это опять я, с часами
От: c-smile Канада http://terrainformatica.com
Дата: 08.11.05 05:23
Оценка: 84 (4)
(извиняюсь за назойливость)

Они ходят

Это вот иллюстрация к тому что я имел ввиду здесь:
http://rsdn.ru/Forum/Message.aspx?mid=1473872&only=1
Автор: c-smile
Дата: 07.11.05


Этот самый behavior:clock в действии.



HTMLayout рисует элементы в три захода:
background, content и foreground

Данный конкретный behavior перекрывает только рисование content.

CSS задает две картинки
background:
и foreground:
(Последняя полупрозрачная — стекло — IE не умеет рисовать альфу).

Вот как выглядит CSS:

.clock {
   behavior:clock; /* name defined in behavior_clock.cpp */
   color:black; /* our behavior will use it for "hands" */
   width:153px;
   height:153px;

   /* clock face */       
   background-image:url(clock-images/clock-back.png);
   background-repeat:no-repeat;       
   background-position:50% 50%; /* middle center */
       
   /* clock glass */       
   foreground-image:url(clock-images/clock-fore.png);
   foreground-repeat:no-repeat;       
   foreground-position:50% 50%; /* middle center */
}


Т.е. в данном конкретном случае мы "реюзаем" все добавляя только
отрисовку контента.

Вот полный текст behavior_clock.cpp который оживляет картину:
(извиняюсь за полный текст, он не большой)


#include "stdafx.h"
#include "behavior_aux.h"

#include <math.h>

namespace htmlayout 
{

/*
BEHAVIOR: clock
    goal: Renders analog clock according to current tome.
TYPICAL USE CASE:
    <img style="behavior:clock">
SAMPLE:
    html_samples/behaviors/live-clock.htm
*/

struct clock: public behavior
{
    // ctor
    clock(): behavior(HANDLE_TIMER | HANDLE_DRAW, "clock") {} // здесь задается имя behavior для CSS

    virtual void attached  (HELEMENT he ) 
    { 
      HTMLayoutSetTimer( he, 1000 ); // set one second timer      
    } 

    virtual void detached  (HELEMENT he ) 
    { 
      HTMLayoutSetTimer( he, 0 ); // remove timer
    } 

    virtual BOOL on_timer  (HELEMENT he ) 
    { 
      dom::element el = he;
      RECT rc = el.get_location(false);
      HWND hw = el.get_element_hwnd(false);
      ::InvalidateRect(hw, &rc, FALSE);
      return TRUE; /*keep going*/ 
    }

    virtual BOOL on_draw   (HELEMENT he, UINT draw_type, HDC hdc, const RECT& rc ) 
    { 
      if( draw_type != DRAW_CONTENT ) return FALSE; /* do default draw if not DRAW_CONTENT */ 

      // we can get color settings from attributes but for simplicity lets use 
      // default values
            
      SYSTEMTIME st;
      GetLocalTime(&st);
      //Use GetSystemTime(&st); - if you need clocks in UTC or other TZ
      //you may use something like get_attribute("timezone")

      draw_clock_hand(hdc,rc, (st.wHour * 360) / 12, 0);
      draw_clock_hand(hdc,rc, (st.wMinute * 360) / 60, 1);
      draw_clock_hand(hdc,rc, (st.wSecond * 360) / 60, 2);
      
      return TRUE; /*skip default draw as we did it already*/ 
    }

    void draw_clock_hand( HDC hdc, const RECT& rc, int angle_degree, int hand )
    {
       double radians = (2 * 3.1415926 * (angle_degree - 90)) / 360.0 ;
       int radius = min( rc.bottom - rc.top, rc.right - rc.left ) / 2 - 12;
       
       HPEN hp = 0;
       LOGBRUSH logbrush = { BS_SOLID, RGB(0,0,0), 0 };
       logbrush.lbColor = ::GetTextColor(hdc);

       switch(hand)
       {
        case 0: // hours
           radius = (radius * 3) / 4; 
           hp = ::ExtCreatePen(PS_GEOMETRIC | PS_SOLID | PS_ENDCAP_ROUND, 5, &logbrush, 0,0);
           break;
        case 1: // minutes
           hp = ::ExtCreatePen(PS_GEOMETRIC | PS_SOLID | PS_ENDCAP_ROUND, 3, &logbrush, 0,0);
           break;
        case 2: // seconds
           logbrush.lbColor = RGB(0x7f,0,0);
           hp = ::ExtCreatePen(PS_GEOMETRIC | PS_SOLID, 1, &logbrush, 0,0);
           break;
        default:
           assert(false);
       }

       int y = (rc.bottom + rc.top) / 2;
       int x = (rc.right + rc.left) / 2;

       int xe = x + cos(radians) * radius;
       int ye = y + sin(radians) * radius;

       HGDIOBJ hpBefore = ::SelectObject(hdc,hp);
       ::MoveToEx(hdc,x,y,0);
       ::LineTo(hdc,xe,ye);
       ::SelectObject(hdc,hpBefore);
       ::DeleteObject(hp);

    }
   
};

// instantiating and attaching it to the global list
clock clock_instance; // регистрация behavior для CSS


} // htmlayout namespace

--EOF

Это собственно демонстрация идеи: UI можно в принципе делать "малой кровью"
программируя только то что действительно надо прогаммировать.

Еще раз извиняюсь за настырность.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.