Wednesday, September 26, 2012

C++ Class Extend and Member Scope



Introduction

A simple practice of C++ class extend and member scope:

public member can be accessed by any object
protected member can be accessed by self and sub classes
private member can be accessed by self only

Test Sample

BaseClass.h

class BaseClass {
    // sub class and any other object can access public member directly
    public: 
        int _varOne; // public member field
        BaseClass()
        {
            _varOne = 0;
            _varTwo = 0;
            _varThree = 0;       
        }
        // where _varOne(varOne) denotes assign varOne to _varOne
        BaseClass (int varOne, int varTwo, int varThree) : _varOne(varOne),
                _varTwo(varTwo), _varThree(varThree)
        {
        }
        int getVarOne ()
        {
            return _varOne;
        }
        int getVarTwo ()
        {
            return _varTwo;
        }
        int getVarThree ()
        {
            return _varThree;
        }
    // sub class can access protected member directly
    // any other object cannot access protected member directly
    protected:
        int _varTwo; // protected member field
    // sub class and any other object cannot access private member directly
    private:
        int _varThree; // private member field
}; 


ExtendedClass.h


#include <iostream>
#include "BaseClass.h"

using namespace std;

/** Extends BaseClass
 * then can access all public/protected member of
 * BaseClass directly in ExtendedClass
 */
class ExtendedClass : public BaseClass {
    public:
        ExtendedClass ()
        {
            // will call super class' basic constructor
            _varFour = 0;
        }
        // call constructor in super class
        ExtendedClass (int varOne, int varTwo, int varThree, int varFour) : BaseClass (varOne, varTwo, varThree),
                _varFour(varFour) // then assign value
        {
        }
        int getVarFour ()
        {
            return _varFour;
        }
        void showAll ()
        {
            cout << "\tvarOne: " << _varOne << endl // _varOne is public
                << "\tvarTwo: " << _varTwo << endl // _varTwo is protected
                << "\tvarThree: " << getVarThree() << endl // _varThree is private member in super class

            // Error! cannot access super class' private member
            // <<"varThree: " << _varThree << endl

                << "\tvarFour: " << _varFour << endl << endl; // _varFour is in this class
        }
    private:
        int _varFour;
};


test.cpp


#include <iostream>
#include "ExtendedClass.h"

using namespace std;

int main() {
    ExtendedClass e1;
    ExtendedClass e2(1, 2, 3, 4);

    cout << "\te2._varOne: " << e2._varOne << endl << endl;
    cout << "\te2._varTwo: " << e2.getVarTwo() << endl << endl;
    cout << "\te2._varThree: " << e2.getVarThree() << endl << endl;
    cout << "\te2._varFour: " << e2.getVarFour() << endl << endl;


    // Error! _varTwo is protected member in e2's super class
    // can only access it directly in BaseClass or ExtendedClass
    // cout << "e2._varTwo: " << e2._varTwo << endl << endl;

    // Error! _varThree is private member in e2's super class
    // cout << "e2._varThree: " << e2._varThree << endl << endl;

    // Error! _varFour is private member in e2's class
    // cout << "e2._varFour: " << e2._varFour << endl << endl;

    e1.showAll();
    e2.showAll();
    system("PAUSE");
}


The Result




Reference

http://www.cplusplus.com/doc/tutorial/inheritance/


Download

Files at github
https://github.com/benbai123/C_Cplusplus_Practice/tree/master/CPP/CPP_Basic/CPP_Extend_and_scope

Monday, September 17, 2012

C/C++ escape characters and operator order

Simple note

escape characters

\a: alert bell
\b: backspace
\f: formfeed
\n: newline
\r: return
\t: horizontal tab
\v: vertical tab
\\: backslash
\?: question mark
\': single quote
\": double quote

operator order
1    ::     Scope resolution     Left-to-right
2    ++   --     Suffix/postfix increment and decrement
    ()     Function call
    []     Array subscripting
    .     Element selection by reference
    ?>     Element selection through pointer
3    ++   --     Prefix increment and decrement     Right-to-left
    +   ?     Unary plus and minus
    !   ~     Logical NOT and bitwise NOT
    (type)     Type cast
    *     Indirection (dereference)
    &     Address-of
    sizeof     Size-of
    new, new[]     Dynamic memory allocation
    delete, delete[]     Dynamic memory deallocation
4    .*   ->*     Pointer to member     Left-to-right
5    *   /   %     Multiplication, division, and remainder
6    +   ?     Addition and subtraction
7    <<   >>     Bitwise left shift and right shift
8    <   <=     For relational operators < and ? respectively
    >   >=     For relational operators > and ? respectively
9    ==   !=     For relational = and ≠ respectively
10    &     Bitwise AND
11    ^     Bitwise XOR (exclusive or)
12    |     Bitwise OR (inclusive or)
13    &&     Logical AND
14    ||     Logical OR
15    ?:     Ternary conditional     Right-to-left
    =     Direct assignment (provided by default for C++ classes)
    +=   ?=     Assignment by sum and difference
    *=   /=   %=     Assignment by product, quotient, and remainder
    <<=   >>=     Assignment by bitwise left shift and right shift
    &=   ^=   |=     Assignment by bitwise AND, XOR, and OR
16    throw     Throw operator (for exceptions)
17    ,     Comma     Left-to-right


Reference

http://www.developerz.com/cplusplus_escapesequences.htm
http://en.cppreference.com/w/cpp/language/operator_precedence

Sunday, September 16, 2012

Use Google Places Autocomplete with ZK Gmaps


Introduction

Places Autocomplete

From Google Maps JavaScript API v3 Reference:


The Places Autocomplete feature attaches to a text field on your web page, and monitors that field for character entries. As text is entered, Autocomplete returns Place predictions to the application in the form of a drop-down pick list.

When a user selects a Place from the list, information about the Place is returned to the Autocomplete object, and can be retrieved by your application.


ZK Gmaps

From ZK Component Reference:

A gmaps is a maps component that wraps the famous Google Maps service that you can control it and embedded it in your ZK web application page in pure Java.



This post is about how to use Google Maps Places Autocomplete with ZK Gmaps.

The Program

geo_autocomplete_test.zul

<zk xmlns:w="client">
    <!-- 
        Tested with ZK 6.0.2 and ZK-Gmaps 3.0.1
     -->
    <script type="text/javascript"><![CDATA[
        function init (wgt) {
            var loadAPI = setInterval(function() {
                // wait until places library ready
                if (window.google && window.google.maps && window.google.maps.places) {
                    var maps = google.maps,
                        complete = wgt._autocomplete = new google.maps.places.Autocomplete(wgt.getInputNode());

                    // listen to google's place_changed event
                    wgt._placeChanged = google.maps.event.addListener(wgt._autocomplete, 'place_changed', function () {
                        var p = complete.getPlace();
                        // triggered wrong
                        if (!p || !p.geometry)
                            return;
                        // prepare event data
                        var node = jq(wgt.getInputNode()),
                            location = p.geometry.location,
                            data = {place: p,
                                    lat: location.lat(),
                                    lng: location.lng()};
                        // fire onPlaceChanged event to CustomTextbox
                        wgt.fire('onPlaceChanged', data);
                    });
                    clearInterval(loadAPI);
                }
            }, 100);
        }
    ]]></script>
    <!-- This textbox uses the CustomTextbox which
        listen to onPlaceChanged event to receive the
        lat/lng from Google Maps Places Autocomplete
     -->
    <div style="margin: 20px;">
        <textbox use="test.geo.autocomplete.CustomTextbox">
            <attribute w:name="bind_"><![CDATA[
                function (a, b, c) {
                    // call original bind_ function
                    this.$bind_(a, b, c);
                    // attach to geo-autocomplete
                    init (this);
                }        
            ]]></attribute>
            <attribute name="onPlaceChanged"><![CDATA[
                import test.geo.autocomplete.PlaceChangedEvent;
                PlaceChangedEvent evt = (PlaceChangedEvent)event;
                gmap.setLat(evt.getLat());
                gmap.setLng(evt.getLng());
            ]]></attribute>
        </textbox>
        <!-- load Google Maps Places library
            by gmaps
         -->
        <gmaps id="gmap" width="500px" height="500px"
            libraries="geometry,places" />
    </div>
</zk>


We create a textbox with CustomTextbox class and use the input node of textbox to create google.maps.places.Autocomplete, fire onPlaceChanged event as need.

CustomTextbox.java

package test.geo.autocomplete;

import java.util.Map;

import org.zkoss.zk.ui.event.Events;
import org.zkoss.zul.Textbox;
/**
 * Tested with ZK 6.0.2 and ZK-Gmaps 3.0.1
 */
public class CustomTextbox extends Textbox {
    // listen to onPlaceChanged event with specific config
    static {
        addClientEvent(CustomTextbox.class, "onPlaceChanged",
                CE_IMPORTANT|CE_DUPLICATE_IGNORE);
    }
    public void service(org.zkoss.zk.au.AuRequest request, boolean everError) {
        final String cmd = request.getCommand();
        // handle event if it is onPlaceChanged event
        if ("onPlaceChanged".equals(cmd)) {
            // get data
            final Map data = request.getData();
            double lat = ((Double) data.get("lat")).doubleValue();
            double lng = ((Double) data.get("lng")).doubleValue();
            // create and post event
            PlaceChangedEvent evt = new PlaceChangedEvent(cmd, lat, lng);
            // post event to the custom textbox
            Events.postEvent(this, evt);
        } else {
            super.service(request, everError);
        }
    }
}


The CustomTextbox listen to onPlaceChanged event and post PlaceChangedEvent event as need.

PlaceChangedEvent.java


package test.geo.autocomplete;

import org.zkoss.zk.ui.event.Event;

/**
 * Tested with ZK 6.0.2 and ZK-Gmaps 3.0.1
 */
public class PlaceChangedEvent extends Event {

    private static final long serialVersionUID = 7538146314204639298L;
    double _lat;
    double _lng;
    public PlaceChangedEvent(String name, double lat, double lng) {
        super(name);
        _lat = lat;
        _lng = lng;
    }
    public Double getLat () {
        return _lat;
    }
    public Double getLng () {
        return _lng;
    }
}

Use this event to store the lat/lng info.

The Result
View demo on line
http://screencast.com/t/GtsCMZ4JiNeD


Reference
https://developers.google.com/maps/documentation/javascript/places


Download

Demo flash at github
https://github.com/benbai123/ZK_Practice/blob/master/Components/demos/addon/GEOAutocomplete.swf

Full project at github
https://github.com/benbai123/ZK_Practice/tree/master/Components/projects/Addon_Practice/GmapsPractice

Sunday, September 9, 2012

ZK: Adding abort button to busy mask



Introduction

In ZK, we can use a mask to prevent any action during a long operation, sometimes we may want to provide 'abort' function to terminate the long operation.

In this case, we can use Client Side Programming to add some widget (with respect to the abort function) into the mask instead of recreating or custommizing the UI completely.

This post will show how to add an abort button into the 'busy' mask to provide the 'abort' function to terminate a long operation.

The Program

adding_abort_button_to_busy_mask.zul

<zk>
    <script type="text/javascript"><![CDATA[
        function showBusy () {
            // show busy mask
            zAu.cmd0.showBusy('Loading...');
            // move abort button under busy message
            jq('.z-loading')[0].appendChild(jq('$abortButton')[0]);
        }
        function clearBusy () {
            // move abort button back under abort div
            jq('$abortDiv')[0].appendChild(jq('$abortButton')[0]);
            // clear busy mask
            zAu.cmd0.clearBusy(null);
        }
    ]]></script>
    <zscript><![CDATA[
        /** A class that implement Runnable to do
         * the long operation
         */
        class AbortableRunnable implements Runnable {
            boolean stopped = true;
            int i = 0;
            public void run () {
                stopped = false;
                while (true) {
                    // do somoething
                    i++;
                    try {
                        Thread.sleep(1000);
                    } catch (Exception e) {
                        System.out.println(e);
                    }
                    // finish or aborted
                    if (i == 5 || stopped)
                        break;
                }
            }
            public void abort () {
                stopped = true;
            }
            public boolean isRunning () {
                return !stopped;
            }
            public int getI () {
                return i;
            }
        }
        AbortableRunnable ar = new AbortableRunnable();
        
        void start () {
            // start thread
            new Thread(ar).start();
        }
        void abort () {
            // update status
            status.setValue("aborted i = " + ar.getI());
            // stop thread
            ar.abort();
            // reset
            ar = new AbortableRunnable();
        }
        void finish () {
            // update status
            status.setValue("finished i = " + ar.getI());
            // reset
            ar = new AbortableRunnable();
        }
    ]]></zscript>
    <!-- abort div to keep the abort button,
        display outside the screen -->
    <div id="abortDiv" style="position: absolute; left: -1000px;">
        <!-- abort button stop the running thread any time
            and clear busy mask -->
        <button id="abortButton" label="abort">
            <attribute name="onClick">
                // abort the running process
                abort();
                // stop the checking timer
                checkTimer.stop();
                // move self element back to abort div
                // and clear the busy mask
                Clients.evalJavaScript("clearBusy();");
            </attribute>
        </button>
    </div>
    <div style="margin: 50px;">
        <!-- start button atart the thread
            and show busy mask -->
        <button label="do something long">
            <attribute name="onClick">
                // start to run the process
                start();
                // start the checking timer
                checkTimer.start();
                // show busy mask and move
                // the element of abort button under busy message
                Clients.evalJavaScript("showBusy();");
            </attribute>
        </button>
        <!-- checking timer clear busy mask after thread finished successfully -->
        <timer id="checkTimer" running="false" repeats="true" delay="100">
            <attribute name="onTimer">
                if (ar.isRunning()) // update status if is running
                    status.setValue("running... i = " + ar.getI());
                if (ar.getI() == 5) { // finish condition
                    finish();
                    // stop self
                    self.stop();
                    // move self element back to abort div
                    // and clear the busy mask
                    Clients.evalJavaScript("clearBusy();");
                }
            </attribute>
        </timer>
        Status: <label id="status" value="" />
    </div>
</zk>


The Result

View the demo flash on line
http://screencast.com/t/jIQV4hr7HlJy

Reference
http://ben-bai.blogspot.tw/2012/07/introduction-sometimes-we-may-need-to.html

Download

Source code at github
https://github.com/benbai123/ZK_Practice/blob/master/Components/projects/Components_Practice/WebContent/adding_abort_button_to_busy_mask.zul

Demo flash at github
https://github.com/benbai123/ZK_Practice/blob/master/Components/demos/adding_abort_button_to_busy_mask.swf