Your IP : 216.73.216.209


Current Path : /usr/include/
Upload File :
Current File : //usr/include/cursesm.h

// * This makes emacs happy -*-Mode: C++;-*-
/****************************************************************************
 * Copyright (c) 1998-2011,2012 Free Software Foundation, Inc.              *
 *                                                                          *
 * Permission is hereby granted, free of charge, to any person obtaining a  *
 * copy of this software and associated documentation files (the            *
 * "Software"), to deal in the Software without restriction, including      *
 * without limitation the rights to use, copy, modify, merge, publish,      *
 * distribute, distribute with modifications, sublicense, and/or sell       *
 * copies of the Software, and to permit persons to whom the Software is    *
 * furnished to do so, subject to the following conditions:                 *
 *                                                                          *
 * The above copyright notice and this permission notice shall be included  *
 * in all copies or substantial portions of the Software.                   *
 *                                                                          *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
 *                                                                          *
 * Except as contained in this notice, the name(s) of the above copyright   *
 * holders shall not be used in advertising or otherwise to promote the     *
 * sale, use or other dealings in this Software without prior written       *
 * authorization.                                                           *
 ****************************************************************************/

/****************************************************************************
 *   Author: Juergen Pfeifer, 1997                                          *
 ****************************************************************************/

// $Id: cursesm.h,v 1.29 2012/12/29 21:48:33 tom Exp $

#ifndef NCURSES_CURSESM_H_incl
#define NCURSES_CURSESM_H_incl 1

#include <cursesp.h>

extern "C" {
#  include <menu.h>
}
//
// -------------------------------------------------------------------------
// This wraps the ITEM type of <menu.h>
// -------------------------------------------------------------------------
//
class NCURSES_IMPEXP NCursesMenuItem
{
  friend class NCursesMenu;

protected:
  ITEM *item;

  inline void OnError (int err) const THROW2(NCursesException const, NCursesMenuException) {
    if (err != E_OK)
      THROW(new NCursesMenuException (err));
  }

public:
  NCursesMenuItem (const char* p_name     = NULL,
		   const char* p_descript = NULL)
    : item(0)
  {
    item = p_name ? ::new_item (p_name, p_descript) : STATIC_CAST(ITEM*)(0);
    if (p_name && !item)
      OnError (E_SYSTEM_ERROR);
  }
  // Create an item. If you pass both parameters as NULL, a delimiting
  // item is constructed which can be used to terminate a list of
  // NCursesMenu objects.

  NCursesMenuItem& operator=(const NCursesMenuItem& rhs)
  {
    if (this != &rhs) {
      *this = rhs;
    }
    return *this;
  }

  NCursesMenuItem(const NCursesMenuItem& rhs)
    : item(0)
  {
    (void) rhs;
  }

  virtual ~NCursesMenuItem ();
  // Release the items memory

  inline const char* name () const {
    return ::item_name (item);
  }
  // Name of the item

  inline const char* description () const {
    return ::item_description (item);
  }
  // Description of the item

  inline int (index) (void) const {
    return ::item_index (item);
  }
  // Index of the item in an item array (or -1)

  inline void options_on (Item_Options opts) {
    OnError (::item_opts_on (item, opts));
  }
  // Switch on the items options

  inline void options_off (Item_Options opts) {
    OnError (::item_opts_off (item, opts));
  }
  // Switch off the item's option

  inline Item_Options options () const {
    return ::item_opts (item);
  }
  // Retrieve the items options

  inline void set_options (Item_Options opts) {
    OnError (::set_item_opts (item, opts));
  }
  // Set the items options

  inline void set_value (bool f) {
    OnError (::set_item_value (item,f));
  }
  // Set/Reset the items selection state

  inline bool value () const {
    return ::item_value (item);
  }
  // Retrieve the items selection state

  inline bool visible () const {
    return ::item_visible (item);
  }
  // Retrieve visibility of the item

  virtual bool action();
  // Perform an action associated with this item; you may use this in an
  // user supplied driver for a menu; you may derive from this class and
  // overload action() to supply items with different actions.
  // If an action returns true, the menu will be exited. The default action
  // is to do nothing.
};

// Prototype for an items callback function.
typedef bool ITEMCALLBACK(NCursesMenuItem&);

// If you don't like to create a child class for individual items to
// overload action(), you may use this class and provide a callback
// function pointer for items.
class NCURSES_IMPEXP NCursesMenuCallbackItem : public NCursesMenuItem
{
private:
  ITEMCALLBACK* p_fct;

public:
  NCursesMenuCallbackItem(ITEMCALLBACK* fct       = NULL,
			  const char* p_name      = NULL,
			  const char* p_descript  = NULL )
    : NCursesMenuItem (p_name, p_descript),
      p_fct (fct) {
  }

  NCursesMenuCallbackItem& operator=(const NCursesMenuCallbackItem& rhs)
  {
    if (this != &rhs) {
      *this = rhs;
    }
    return *this;
  }

  NCursesMenuCallbackItem(const NCursesMenuCallbackItem& rhs)
    : NCursesMenuItem(rhs),
      p_fct(0)
  {
  }

  virtual ~NCursesMenuCallbackItem();

  bool action();
};

  // This are the built-in hook functions in this C++ binding. In C++ we use
  // virtual member functions (see below On_..._Init and On_..._Termination)
  // to provide this functionality in an object oriented manner.
extern "C" {
  void _nc_xx_mnu_init(MENU *);
  void _nc_xx_mnu_term(MENU *);
  void _nc_xx_itm_init(MENU *);
  void _nc_xx_itm_term(MENU *);
}

//
// -------------------------------------------------------------------------
// This wraps the MENU type of <menu.h>
// -------------------------------------------------------------------------
//
class NCURSES_IMPEXP NCursesMenu : public NCursesPanel
{
protected:
  MENU *menu;

private:
  NCursesWindow* sub;   // the subwindow object
  bool b_sub_owner;     // is this our own subwindow?
  bool b_framed;        // has the menu a border?
  bool b_autoDelete;    // Delete items when deleting menu?

  NCursesMenuItem** my_items; // The array of items for this menu

  // This structure is used for the menu's user data field to link the
  // MENU* to the C++ object and to provide extra space for a user pointer.
  typedef struct {
    void*              m_user;      // the pointer for the user's data
    const NCursesMenu* m_back;      // backward pointer to C++ object
    const MENU*        m_owner;
  } UserHook;

  // Get the backward pointer to the C++ object from a MENU
  static inline NCursesMenu* getHook(const MENU *m) {
    UserHook* hook = STATIC_CAST(UserHook*)(::menu_userptr(m));
    assert(hook != 0 && hook->m_owner==m);
    return const_cast<NCursesMenu*>(hook->m_back);
  }

  friend void _nc_xx_mnu_init(MENU *);
  friend void _nc_xx_mnu_term(MENU *);
  friend void _nc_xx_itm_init(MENU *);
  friend void _nc_xx_itm_term(MENU *);

  // Calculate ITEM* array for the menu
  ITEM** mapItems(NCursesMenuItem* nitems[]);

protected:
  // internal routines
  inline void set_user(void *user) {
    UserHook* uptr = STATIC_CAST(UserHook*)(::menu_userptr (menu));
    assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==menu);
    uptr->m_user = user;
  }

  inline void *get_user() {
    UserHook* uptr = STATIC_CAST(UserHook*)(::menu_userptr (menu));
    assert (uptr != 0 && uptr->m_back==this && uptr->m_owner==menu);
    return uptr->m_user;
  }

  void InitMenu (NCursesMenuItem* menu[],
		 bool with_frame,
		 bool autoDeleteItems);

  inline void OnError (int err) const THROW2(NCursesException const, NCursesMenuException) {
    if (err != E_OK)
      THROW(new NCursesMenuException (this, err));
  }

  // this wraps the menu_driver call.
  virtual int driver (int c) ;

  // 'Internal' constructor to create a menu without association to
  // an array of items.
  NCursesMenu( int  nlines,
	       int  ncols,
	       int  begin_y = 0,
	       int  begin_x = 0)
    : NCursesPanel(nlines,ncols,begin_y,begin_x),
      menu (STATIC_CAST(MENU*)(0)),
      sub(0),
      b_sub_owner(0),
      b_framed(0),
      b_autoDelete(0),
      my_items(0)
  {
  }

public:
  // Make a full window size menu
  NCursesMenu (NCursesMenuItem* Items[],
	       bool with_frame=FALSE,        // Reserve space for a frame?
	       bool autoDelete_Items=FALSE)  // Autocleanup of Items?
    : NCursesPanel(),
      menu(0),
      sub(0),
      b_sub_owner(0),
      b_framed(0),
      b_autoDelete(0),
      my_items(0)
  {
      InitMenu(Items, with_frame, autoDelete_Items);
  }

  // Make a menu with a window of this size.
  NCursesMenu (NCursesMenuItem* Items[],
	       int  nlines,
	       int  ncols,
	       int  begin_y = 0,
	       int  begin_x = 0,
	       bool with_frame=FALSE,        // Reserve space for a frame?
	       bool autoDelete_Items=FALSE)  // Autocleanup of Items?
    : NCursesPanel(nlines, ncols, begin_y, begin_x),
      menu(0),
      sub(0),
      b_sub_owner(0),
      b_framed(0),
      b_autoDelete(0),
      my_items(0)
  {
      InitMenu(Items, with_frame, autoDelete_Items);
  }

  NCursesMenu& operator=(const NCursesMenu& rhs)
  {
    if (this != &rhs) {
      *this = rhs;
      NCursesPanel::operator=(rhs);
    }
    return *this;
  }

  NCursesMenu(const NCursesMenu& rhs)
    : NCursesPanel(rhs),
      menu(rhs.menu),
      sub(rhs.sub),
      b_sub_owner(rhs.b_sub_owner),
      b_framed(rhs.b_framed),
      b_autoDelete(rhs.b_autoDelete),
      my_items(rhs.my_items)
  {
  }

  virtual ~NCursesMenu ();

  // Retrieve the menus subwindow
  inline NCursesWindow& subWindow() const {
    assert(sub!=NULL);
    return *sub;
  }

  // Set the menus subwindow
  void setSubWindow(NCursesWindow& sub);

  // Set these items for the menu
  inline void setItems(NCursesMenuItem* Items[]) {
    OnError(::set_menu_items(menu,mapItems(Items)));
  }

  // Remove the menu from the screen
  inline void unpost (void) {
    OnError (::unpost_menu (menu));
  }

  // Post the menu to the screen if flag is true, unpost it otherwise
  inline void post(bool flag = TRUE) {
    flag ? OnError (::post_menu(menu)) : OnError (::unpost_menu (menu));
  }

  // Get the numer of rows and columns for this menu
  inline void scale (int& mrows, int& mcols) const  {
    OnError (::scale_menu (menu, &mrows, &mcols));
  }

  // Set the format of this menu
  inline void set_format(int mrows, int mcols) {
    OnError (::set_menu_format(menu, mrows, mcols));
  }

  // Get the format of this menu
  inline void menu_format(int& rows,int& ncols) {
    ::menu_format(menu,&rows,&ncols);
  }

  // Items of the menu
  inline NCursesMenuItem* items() const {
    return *my_items;
  }

  // Get the number of items in this menu
  inline int count() const {
    return ::item_count(menu);
  }

  // Get the current item (i.e. the one the cursor is located)
  inline NCursesMenuItem* current_item() const {
    return my_items[::item_index(::current_item(menu))];
  }

  // Get the marker string
  inline const char* mark() const {
    return ::menu_mark(menu);
  }

  // Set the marker string
  inline void set_mark(const char *marker) {
    OnError (::set_menu_mark (menu, marker));
  }

  // Get the name of the request code c
  inline static const char* request_name(int c) {
    return ::menu_request_name(c);
  }

  // Get the current pattern
  inline char* pattern() const {
    return ::menu_pattern(menu);
  }

  // true if there is a pattern match, false otherwise.
  bool set_pattern (const char *pat);

  // set the default attributes for the menu
  // i.e. set fore, back and grey attribute
  virtual void setDefaultAttributes();

  // Get the menus background attributes
  inline chtype back() const {
    return ::menu_back(menu);
  }

  // Get the menus foreground attributes
  inline chtype fore() const {
    return ::menu_fore(menu);
  }

  // Get the menus grey attributes (used for unselectable items)
  inline chtype grey() const {
    return ::menu_grey(menu);
  }

  // Set the menus background attributes
  inline chtype set_background(chtype a) {
    return ::set_menu_back(menu,a);
  }

  // Set the menus foreground attributes
  inline chtype set_foreground(chtype a) {
    return ::set_menu_fore(menu,a);
  }

  // Set the menus grey attributes (used for unselectable items)
  inline chtype set_grey(chtype a) {
    return ::set_menu_grey(menu,a);
  }

  inline void options_on (Menu_Options opts) {
    OnError (::menu_opts_on (menu,opts));
  }

  inline void options_off(Menu_Options opts) {
    OnError (::menu_opts_off(menu,opts));
  }

  inline Menu_Options options() const {
    return ::menu_opts(menu);
  }

  inline void set_options (Menu_Options opts) {
    OnError (::set_menu_opts (menu,opts));
  }

  inline int pad() const {
    return ::menu_pad(menu);
  }

  inline void set_pad (int padch) {
    OnError (::set_menu_pad (menu, padch));
  }

  // Position the cursor to the current item
  inline void position_cursor () const {
    OnError (::pos_menu_cursor (menu));
  }

  // Set the current item
  inline void set_current(NCursesMenuItem& I) {
    OnError (::set_current_item(menu, I.item));
  }

  // Get the current top row of the menu
  inline int top_row (void) const {
    return ::top_row (menu);
  }

  // Set the current top row of the menu
  inline void set_top_row (int row) {
    OnError (::set_top_row (menu, row));
  }

  // spacing control
  // Set the spacing for the menu
  inline void setSpacing(int spc_description,
			 int spc_rows,
			 int spc_columns) {
    OnError(::set_menu_spacing(menu,
			       spc_description,
			       spc_rows,
			       spc_columns));
  }

  // Get the spacing info for the menu
  inline void Spacing(int& spc_description,
		      int& spc_rows,
		      int& spc_columns) const {
    OnError(::menu_spacing(menu,
			   &spc_description,
			   &spc_rows,
			   &spc_columns));
  }

  // Decorations
  inline void frame(const char *title=NULL, const char* btitle=NULL) {
    if (b_framed)
      NCursesPanel::frame(title,btitle);
    else
      OnError(E_SYSTEM_ERROR);
  }

  inline void boldframe(const char *title=NULL, const char* btitle=NULL) {
    if (b_framed)
      NCursesPanel::boldframe(title,btitle);
    else
      OnError(E_SYSTEM_ERROR);
  }

  inline void label(const char *topLabel, const char *bottomLabel) {
    if (b_framed)
      NCursesPanel::label(topLabel,bottomLabel);
    else
      OnError(E_SYSTEM_ERROR);
  }

  // -----
  // Hooks
  // -----

  // Called after the menu gets repositioned in its window.
  // This is especially true if the menu is posted.
  virtual void On_Menu_Init();

  // Called before the menu gets repositioned in its window.
  // This is especially true if the menu is unposted.
  virtual void On_Menu_Termination();

  // Called after the item became the current item
  virtual void On_Item_Init(NCursesMenuItem& item);

  // Called before this item is left as current item.
  virtual void On_Item_Termination(NCursesMenuItem& item);

  // Provide a default key virtualization. Translate the keyboard
  // code c into a menu request code.
  // The default implementation provides a hopefully straightforward
  // mapping for the most common keystrokes and menu requests.
  virtual int virtualize(int c);


  // Operators
  inline NCursesMenuItem* operator[](int i) const {
    if ( (i < 0) || (i >= ::item_count (menu)) )
      OnError (E_BAD_ARGUMENT);
    return (my_items[i]);
  }

  // Perform the menu's operation
  // Return the item where you left the selection mark for a single
  // selection menu, or NULL for a multivalued menu.
  virtual NCursesMenuItem* operator()(void);

  // --------------------
  // Exception handlers
  // Called by operator()
  // --------------------

  // Called if the request is denied
  virtual void On_Request_Denied(int c) const;

  // Called if the item is not selectable
  virtual void On_Not_Selectable(int c) const;

  // Called if pattern doesn't match
  virtual void On_No_Match(int c) const;

  // Called if the command is unknown
  virtual void On_Unknown_Command(int c) const;

};
//
// -------------------------------------------------------------------------
// This is the typical C++ typesafe way to allow to attach
// user data to an item of a menu. Its assumed that the user
// data belongs to some class T. Use T as template argument
// to create a UserItem.
// -------------------------------------------------------------------------
//
template<class T> class NCURSES_IMPEXP NCursesUserItem : public NCursesMenuItem
{
public:
  NCursesUserItem (const char* p_name,
		   const char* p_descript = NULL,
		   const T* p_UserData    = STATIC_CAST(T*)(0))
    : NCursesMenuItem (p_name, p_descript) {
      if (item)
	OnError (::set_item_userptr (item, const_cast<void *>(reinterpret_cast<const void*>(p_UserData))));
  }

  virtual ~NCursesUserItem() {}

  inline const T* UserData (void) const {
    return reinterpret_cast<const T*>(::item_userptr (item));
  };

  inline virtual void setUserData(const T* p_UserData) {
    if (item)
      OnError (::set_item_userptr (item, const_cast<void *>(reinterpret_cast<const void *>(p_UserData))));
  }
};
//
// -------------------------------------------------------------------------
// The same mechanism is used to attach user data to a menu
// -------------------------------------------------------------------------
//
template<class T> class NCURSES_IMPEXP NCursesUserMenu : public NCursesMenu
{
protected:
  NCursesUserMenu( int  nlines,
		   int  ncols,
		   int  begin_y = 0,
		   int  begin_x = 0,
		   const T* p_UserData = STATIC_CAST(T*)(0))
    : NCursesMenu(nlines,ncols,begin_y,begin_x) {
      if (menu)
	set_user (const_cast<void *>(p_UserData));
  }

public:
  NCursesUserMenu (NCursesMenuItem* Items[],
		   const T* p_UserData = STATIC_CAST(T*)(0),
		   bool with_frame=FALSE,
		   bool autoDelete_Items=FALSE)
    : NCursesMenu (Items, with_frame, autoDelete_Items) {
      if (menu)
	set_user (const_cast<void *>(p_UserData));
  };

  NCursesUserMenu (NCursesMenuItem* Items[],
		   int nlines,
		   int ncols,
		   int begin_y = 0,
		   int begin_x = 0,
		   const T* p_UserData = STATIC_CAST(T*)(0),
		   bool with_frame=FALSE)
    : NCursesMenu (Items, nlines, ncols, begin_y, begin_x, with_frame) {
      if (menu)
	set_user (const_cast<void *>(p_UserData));
  };

  virtual ~NCursesUserMenu() {
  };

  inline T* UserData (void) const {
    return reinterpret_cast<T*>(get_user ());
  };

  inline virtual void setUserData (const T* p_UserData) {
    if (menu)
      set_user (const_cast<void *>(p_UserData));
  }
};

#endif /* NCURSES_CURSESM_H_incl */

Rosenblum TV: Video training, virtual workshops, classes, tutorials
logologologologo
  • About
  • What We Do
  • Our Clients
  • Case Studies
    • The BBC
    • CBS News
    • New York Times Television
    • Spectrum News
    • The Newark Star-Ledger
    • The United Nations
    • McGraw/Hill
    • Oyster Yachts
    • Scottish Environmental Protection Agency
  • The Power of Storytelling
  • Why iPhones?
  • Michael on Media
  • Books
  • Contact
  • About
  • What We Do
  • Our Clients
  • Case Studies
    • The BBC
    • CBS News
    • New York Times Television
    • Spectrum News
    • The Newark Star-Ledger
    • The United Nations
    • McGraw/Hill
    • Oyster Yachts
    • Scottish Environmental Protection Agency
  • The Power of Storytelling
  • Why iPhones?
  • Michael on Media
  • Books
  • Contact

RE-INVENTING THE TELEVISION NEWS BUSINESS*

A revolution in video storytelling

Creating entirely new & cost-effective production methods

From the world leaders in video production training and the creators of Character Driven Storytelling™

*and every other business that uses video

WHAT WE DO

Over the past 35 years, we have designed, built or restructured some of the most powerful news and journalism companies in the world.

We replace the traditional TV news ‘crew’ with one highly trained journalist, working alone with nothing but an iPhone.

No more TV news ‘crews’, no editors and no field producers.

This is television news done the way newspaper journalism is done – one reporter with their electronic pad and pencil.

In doing this, we can cut the cost of production by as much as 75% while increasing ratings and audience engagement.

In the place of conventional TV news ‘packages’ – ie, reporter stand up, interview, b-roll, man on the street, we marry great journalism with Netflix and Hollywood storytelling.

It’s a combination that works.

We have taken most of our clients to #1 in their respective markets.

And it’s not just for news. Any company, any profit, any NGO and anyone else who is online needs to tell their story in compelling yet cost-effective video. We can teach you to do that. Either in person or virtually.

EXAMPLES OF WHAT WE CAN TEACH YOUR STAFF TO PRODUCE

ITAY HOD

Itay Hod, MMJ with KPIX/CBS in San Francisco, took the 5-Day Intensive Video Storytelling Bootcamp in 2018.

Because he works alone, with only an iPhone, he was able to embed himself with a homeless family.

Here’s the story he produced in a one-day turn.

KIET DO

Kiet Do, an MMJ with KPIX/CBS in San Francisco, took the 5-Day Intensive Video Storytelling Bootcamp in 2021.

Here is a story he produced, all on his own, with only an iPhone and in a one-day turn.

TAYLOR SCHAUB

Taylor Schaub, an MMJ with Spectrum News 1 in LA, took the 5-Day Intensive Video Storytelling Bootcamp in 2023.

Here is a story he turned in only one day, using only an iPhone. It was the first video story he ever did and it was nominated for an Emmy.

THE BOOTCAMP

How do we convert stations and whole networks to working in this way?

Since 1988, we have run intensive 5-Day Video Storytelling Bootcamps

We have done these all over the world.

These are hands-on bootcamps, and participants learn an entirely new way of creating TV news stories.

-We shoot at a 3:1 ratio or lower, so turnaround times are fast.

-We go directly from camera to timelilne and edit – no written scripts.  We work in the medium of pictures and sound.

-We are entirely character-driven.

-We are driven by pictures and real events.

-We are focused almost entirely on ’the viewer experience’.

Since 1988, more than 70,000 journalists around the world have taken our bootcamps, either in person on virtualy.

Case Studies

CBS Case Study Logos
CBS News

We have started to work with CBS News, bringing our ideas of character-driven storytelling to one of the most successful and biggest networks in the United States. Since beginning to work with them ratings have climbed and more importantly, audience engagement is through the ceiling.

Learn More
NYT Case Study Logos
New York Times Television

We started New York Times Television in 1990 and it was the first paper to be brought into the world of TV. It quickly became one of the most successful non-fiction production companies in the United States. The series and documentaries we produced won many awards including multiple Emmys.

Learn More
BBC Case Study Logos
The BBC

We have been working with the BBC since the year 2000 helping to convert their national news network to our visual storytelling technique. Most recently we have trained teams from their sports, documentaries, and comedy divisions to make character-driven stories using only smartphones.

Learn More
Spectrum Case Study Logos
Spectrum News

For the past five years we have worked with Spectrum News to introduce and train their journalists on visual, character driven storytelling using smartphones helping to create a different kind of local news for their network of 24-Hour News Stations across the United States.

Learn More
UN Case Study Logos
The United Nations

In 2006, we were approached by the United Nations. Rather than rely on news outlets, it would be much easier to train the field operatives to produce their own stories. We spent two years working with the UN, training more than 100 of their staff in bootcamps in Geneva and Nairobi.

Learn More
Star Ledger Case Study Logos
The Newark Star-Ledger

We trained 50 print reporters at the paper to shoot and tell their own stories, in conjunction with their print work. We built a TV newsroom in their existing print newsroom – you could not ask for a better set and they began to live stream their stories in conjunction with their print work.

Learn More
Mcgraw Hill Case Study Logos
Mcgraw Hill

We spent two years with McGraw Hill, training more than 150 of their staffers, making them completely video literate. McGraw/Hill media properties we transit included Business Week, Aviation Week, (what was the name of the architecture magazine), and JD Power and Associates.

Learn More
VOA Case Study Logos
Voice of America

In 1990, we were approached by The Voice of America, the official broadcasting agency for the United States Government. When we met with VOA, they were only a short wave radio broadcaster, but working with them, we took them into television, launching VOA-TV.

Learn More
Oyster Case Study Logos
Oyster Yachts

British based Oyster Yachts makes some of the finest yachts in the world. Like every other company, they had to find a way to feed the never-ending video demands of social media – sites like Instagram and TikTok. We trained the Oyster staff to tell their own stories, using only iPhones.

Learn More
SEPA Case Study Logos
Scottish Environmental Protection Agency

We were approached by SEPA, the Scottish Environmental Protection Agency because they had to continually find a way to ‘feed the media beast’. The result was that SEPA was able to tell their own stories, whenever they wanted, and at almost no additional cost.

Learn More
Image 11-11-22 at 6.25 PM

Michael on Media

Michael Rosenblum has been writing about the media since 1988. His work and ideas have appeared in The Guardian, The Huffington Post, Ilkeston Life and many other publications.

He has been blogging regularly for the past 35 years on this subject. Having taught media studies at Columbia University, NYU and now the University of Oxford, he is considered an expert on this subject.

Continue reading this post or look back at previous posts.

Read More

Do You Have Questions About Learning Video Skills?

If you would like to know more about our courses contact us and one of our training advisors will be happy to call you.

Contact Us

Copyright 2024. All rights reserved.